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 <[email protected]>
---
 gcc/ifcvt.cc                                  |  4 ++++
 gcc/testsuite/gcc.dg/pr123294-1.c             | 15 +++++++++++++++
 gcc/testsuite/gcc.target/aarch64/pr123294-1.c | 16 ++++++++++++++++
 3 files changed, 35 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/pr123294-1.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/pr123294-1.c

diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc
index 60fc97a3907..ca996d6ae19 100644
--- a/gcc/ifcvt.cc
+++ b/gcc/ifcvt.cc
@@ -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
index 00000000000..535207993b2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr123294-1.c
@@ -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
index 00000000000..9323b1931de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr123294-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+/* PR rtl-optimization/123294 */
+
+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 (__builtin_aarch64_usadddi_uuu(3, 0))
+    ;
+  return e[0][3];
+}
-- 
2.43.0

Reply via email to