From 92e9e971ced90af5a825ae4b35ad6c98c9ab86da Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Fri, 4 Oct 2024 13:12:45 +0200
Subject: [PATCH] i386: Fix up ix86_expand_int_compare with TImode comparisons
 of SUBREGs from V8{H,B}Fmode against zero [PR116921]

The following testcase ICEs, because the ix86_expand_int_compare
optimization to use {,v}ptest assumes there are instructions for all
16-byte vector modes.  That isn't the case, we only have one for
V16QI, V8HI, V4SI, V2DI, V1TI, V4SF and V2DF, not for
V8HF nor V8BF.

The following patch fixes that by using the V8HI instruction instead
for those 2 modes.  tmp can't be a SUBREG, because it is SUBREG_REG
of another SUBREG, so we don't need to worry about gen_lowpart
failing.

2024-10-04  Jakub Jelinek  <jakub@redhat.com>

	PR target/116921
	* config/i386/i386-expand.cc (ix86_expand_int_compare): Add a SUBREG
	to V8HImode from V8HFmode or V8BFmode before generating a ptest.

	* gcc.target/i386/pr116921.c: New test.
---
 gcc/config/i386/i386-expand.cc           |  2 ++
 gcc/testsuite/gcc.target/i386/pr116921.c | 12 ++++++++++++
 2 files changed, 14 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr116921.c

diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 39ee9b8662ad..a9f83a299e3a 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -3095,6 +3095,8 @@ ix86_expand_int_compare (enum rtx_code code, rtx op0, rtx op1)
       && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))) == 16)
     {
       tmp = SUBREG_REG (op0);
+      if (GET_MODE (tmp) == V8HFmode || GET_MODE (tmp) == V8BFmode)
+	tmp = gen_lowpart (V8HImode, tmp);
       tmp = gen_rtx_UNSPEC (CCZmode, gen_rtvec (2, tmp, tmp), UNSPEC_PTEST);
     }
   else
diff --git a/gcc/testsuite/gcc.target/i386/pr116921.c b/gcc/testsuite/gcc.target/i386/pr116921.c
new file mode 100644
index 000000000000..8cd4cf93b76d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr116921.c
@@ -0,0 +1,12 @@
+/* PR target/116921 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -msse4" } */
+
+long x;
+_Float16 __attribute__((__vector_size__ (16))) f;
+
+void
+foo (void)
+{
+  x -= !(__int128) (f / 2);
+}
-- 
GitLab