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>
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
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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];
+}