neutral_op can be null, so guard against that.
Bootstrapped Regtested on aarch64-none-linux-gnu,
arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
-m32, -m64 and no issues
Pushed to master.
Thanks,
Tamar
gcc/ChangeLog:
PR tree-optimization/122475
* tree-vect-loop.cc (vectorizable_reduction): Check for neutral_op.
gcc/testsuite/ChangeLog:
PR tree-optimization/122475
* gcc.dg/vect/pr122475.c: New test.
* gcc.target/aarch64/sve/vect-reduc-bool-19.c: New test.
* gcc.target/aarch64/sve/vect-reduc-bool-20.c: New test.
---
diff --git a/gcc/testsuite/gcc.dg/vect/pr122475.c
b/gcc/testsuite/gcc.dg/vect/pr122475.c
new file mode 100644
index
0000000000000000000000000000000000000000..ed229c5475cc96fc0ef3beea71b101db89e08916
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr122475.c
@@ -0,0 +1,13 @@
+/* { dg-additional-options "-march=armv8-a+sve" { target aarch64*-*-* } } */
+/* Check that we don't ICE. */
+int a;
+int b;
+int main() {
+ for (char t = 0; t < 14; t += 2)
+ for (int u = 0; u < 242; u += 4) {
+ a = a < 0 ? a : 0;
+ b = b < 0 ? b : 0;
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 1 "vect" {
target aarch64*-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-19.c
b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-19.c
new file mode 100644
index
0000000000000000000000000000000000000000..6492c44c065159d06d7e69499dfc9834721d62ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-19.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mautovec-preference=sve-only
-fdump-tree-vect-details -O3 --param vect-epilogues-nomask=0" } */
+
+int p[128];
+
+bool __attribute__((noipa))
+fand (int n, bool r1, bool r2)
+{
+ bool r = true;
+ for (int i = 0; i < (n/2); i+=2)
+ {
+ r &= (p[i] != 0) & r1;
+ r &= (p[i+1] != 0) & r2;
+ }
+ return r;
+}
+/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 1 "vect" } }
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-20.c
b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-20.c
new file mode 100644
index
0000000000000000000000000000000000000000..83c5c206dd2597c3776317005a3dd38ee5991f16
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-20.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mautovec-preference=sve-only
-fdump-tree-vect-details -O3 --param vect-epilogues-nomask=0" } */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+void vec_slp_cmp (char* restrict a, char* restrict b, int n) {
+ bool x0 = b[0] != 0;
+ bool x1 = b[1] != 0;
+ bool x2 = b[2] != 0;
+ bool x3 = b[3] != 0;
+ for (int i = 0; i < n; ++i) {
+ x0 &= (a[i * 4] != 0);
+ x1 &= (a[i * 4 + 1] != 0);
+ x2 &= (a[i * 4 + 2] != 0);
+ x3 &= (a[i * 4 + 3] != 0);
+ }
+ b[0] = x0;
+ b[1] = x1;
+ b[2] = x2;
+ b[3] = x3;
+}
+
+void vec_slp_cmp1 (char* restrict a, char* restrict b, int n) {
+ bool x0 = b[0] != 0;
+ for (int i = 0; i < n; ++i) {
+ x0 &= (a[i] != 0);
+ }
+ b[0] = x0;
+}
+
+/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 2 "vect" {
target aarch64*-*-* } } } */
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index
50cdc2a90fa29c1e0d116c0589bc246e6d8fcc84..576a69c82d25aa74ce9cc8dbb89d0b340ed9ba39
100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -7578,7 +7578,9 @@ vectorizable_reduction (loop_vec_info loop_vinfo,
if ((double_reduc || neutral_op)
&& !nunits_out.is_constant ()
&& (SLP_TREE_LANES (slp_node) != 1 && !reduc_chain)
- && !operand_equal_p (neutral_op, vect_phi_initial_value (reduc_def_phi))
+ && (!neutral_op
+ || !operand_equal_p (neutral_op,
+ vect_phi_initial_value (reduc_def_phi)))
&& !direct_internal_fn_supported_p (IFN_VEC_SHL_INSERT,
vectype_out, OPTIMIZE_FOR_SPEED))
{
--
diff --git a/gcc/testsuite/gcc.dg/vect/pr122475.c b/gcc/testsuite/gcc.dg/vect/pr122475.c
new file mode 100644
index 0000000000000000000000000000000000000000..ed229c5475cc96fc0ef3beea71b101db89e08916
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr122475.c
@@ -0,0 +1,13 @@
+/* { dg-additional-options "-march=armv8-a+sve" { target aarch64*-*-* } } */
+/* Check that we don't ICE. */
+int a;
+int b;
+int main() {
+ for (char t = 0; t < 14; t += 2)
+ for (int u = 0; u < 242; u += 4) {
+ a = a < 0 ? a : 0;
+ b = b < 0 ? b : 0;
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 1 "vect" { target aarch64*-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-19.c b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-19.c
new file mode 100644
index 0000000000000000000000000000000000000000..6492c44c065159d06d7e69499dfc9834721d62ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-19.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mautovec-preference=sve-only -fdump-tree-vect-details -O3 --param vect-epilogues-nomask=0" } */
+
+int p[128];
+
+bool __attribute__((noipa))
+fand (int n, bool r1, bool r2)
+{
+ bool r = true;
+ for (int i = 0; i < (n/2); i+=2)
+ {
+ r &= (p[i] != 0) & r1;
+ r &= (p[i+1] != 0) & r2;
+ }
+ return r;
+}
+/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 1 "vect" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-20.c b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-20.c
new file mode 100644
index 0000000000000000000000000000000000000000..83c5c206dd2597c3776317005a3dd38ee5991f16
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-20.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mautovec-preference=sve-only -fdump-tree-vect-details -O3 --param vect-epilogues-nomask=0" } */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+void vec_slp_cmp (char* restrict a, char* restrict b, int n) {
+ bool x0 = b[0] != 0;
+ bool x1 = b[1] != 0;
+ bool x2 = b[2] != 0;
+ bool x3 = b[3] != 0;
+ for (int i = 0; i < n; ++i) {
+ x0 &= (a[i * 4] != 0);
+ x1 &= (a[i * 4 + 1] != 0);
+ x2 &= (a[i * 4 + 2] != 0);
+ x3 &= (a[i * 4 + 3] != 0);
+ }
+ b[0] = x0;
+ b[1] = x1;
+ b[2] = x2;
+ b[3] = x3;
+}
+
+void vec_slp_cmp1 (char* restrict a, char* restrict b, int n) {
+ bool x0 = b[0] != 0;
+ for (int i = 0; i < n; ++i) {
+ x0 &= (a[i] != 0);
+ }
+ b[0] = x0;
+}
+
+/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 2 "vect" { target aarch64*-*-* } } } */
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 50cdc2a90fa29c1e0d116c0589bc246e6d8fcc84..576a69c82d25aa74ce9cc8dbb89d0b340ed9ba39 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -7578,7 +7578,9 @@ vectorizable_reduction (loop_vec_info loop_vinfo,
if ((double_reduc || neutral_op)
&& !nunits_out.is_constant ()
&& (SLP_TREE_LANES (slp_node) != 1 && !reduc_chain)
- && !operand_equal_p (neutral_op, vect_phi_initial_value (reduc_def_phi))
+ && (!neutral_op
+ || !operand_equal_p (neutral_op,
+ vect_phi_initial_value (reduc_def_phi)))
&& !direct_internal_fn_supported_p (IFN_VEC_SHL_INSERT,
vectype_out, OPTIMIZE_FOR_SPEED))
{