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