]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ifcvt: Fix store flag of XImode on aarch64 while ifcvt [PR123294]
authorAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Sun, 1 Feb 2026 23:41:52 +0000 (15:41 -0800)
committerAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Mon, 2 Feb 2026 17:48:46 +0000 (09:48 -0800)
In the testcase ifcvt is trying to do a emit_store_flag into a XImode.
That will cause an ICE because XImode does not have any arithmetic optabs
associated with it. This is because it is greater than MAX_FIXED_MODE_SIZE
(along other things).
noce_emit_store_flag already has code to reject non-scalar modes, so
this adds a new check for modes that are greater than MAX_FIXED_MODE_SIZE.

Bootstrapped and tested on aarch64-linux-gnu.

PR rtl-optimization/123294

gcc/ChangeLog:

* ifcvt.cc (noce_emit_store_flag): Reject modes
greater than MAX_FIXED_MODE_SIZE.

gcc/testsuite/ChangeLog:

* gcc.dg/pr123294-1.c: New test.
* gcc.target/aarch64/pr123294-1.c: New test.

Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
gcc/ifcvt.cc
gcc/testsuite/gcc.dg/pr123294-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/pr123294-1.c [new file with mode: 0644]

index 60fc97a3907011bb1fb35e5d7d242cee6e5b2b9d..ca996d6ae19ca77d642e3f2a6e0873ad7a9feb6f 100644 (file)
@@ -891,6 +891,10 @@ noce_emit_store_flag (struct noce_if_info *if_info, rtx x, bool reversep,
   if (cond_complex || !SCALAR_INT_MODE_P (GET_MODE (x)))
     return NULL_RTX;
 
+  /* Don't try if mode of X is more than the max fixed mode size.  */
+  if (known_le (MAX_FIXED_MODE_SIZE, GET_MODE_BITSIZE (GET_MODE (x))))
+    return NULL_RTX;
+
   return emit_store_flag (x, code, XEXP (cond, 0),
                          XEXP (cond, 1), VOIDmode,
                          (code == LTU || code == LEU
diff --git a/gcc/testsuite/gcc.dg/pr123294-1.c b/gcc/testsuite/gcc.dg/pr123294-1.c
new file mode 100644 (file)
index 0000000..5352079
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fno-tree-dse -fno-tree-dce" } */
+/* PR rtl-optimization/123294 */
+
+typedef unsigned a;
+int b;
+void g(__attribute__((__vector_size__(4 * sizeof(a)))) a *);
+a d() {
+  __attribute__((__vector_size__(4 * sizeof(a)))) a e[5];
+  if (0 > b) {
+    __attribute__((__vector_size__(8 * sizeof(a)))) a f = {b, b};
+    e[0] = __builtin_shufflevector(f, f, 0, 1, 2, 3);
+  }
+  return 1;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/pr123294-1.c b/gcc/testsuite/gcc.target/aarch64/pr123294-1.c
new file mode 100644 (file)
index 0000000..1ad9c23
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+/* PR rtl-optimization/123294 */
+
+#include <arm_neon.h>
+
+typedef unsigned a;
+int b;
+a d() {
+  __attribute__((__vector_size__(4 * sizeof(a)))) a e[5];
+  if (0 > b) {
+    __attribute__((__vector_size__(8 * sizeof(a)))) a f = {b, b};
+    e[0] = __builtin_shufflevector(f, f, 0, 1, 2, 3);
+  }
+  while (vqadd_u64((uint64x1_t){3}, (uint64x1_t){0})[0])
+    ;
+  return e[0][3];
+}