The following avoids a mistake with r17-3692 by restoring the
way vectype_in was computed, pushing down the vec_in_num compute
before the input array is possibly mangled.

Bootstrapped and tested on aarch64-linux-gnu, pushed.

        PR tree-optimization/127152
        * tree-vect-loop.cc (vect_transform_reduction): Restore
        vectype_in computation, compute vec_in_num from unaltered
        vec_oprnds.

        * gcc.dg/vect/vect-pr127152.c: New testcase.
---
 gcc/testsuite/gcc.dg/vect/vect-pr127152.c | 29 +++++++++++++++++++++++
 gcc/tree-vect-loop.cc                     |  7 +++---
 2 files changed, 33 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-pr127152.c

diff --git a/gcc/testsuite/gcc.dg/vect/vect-pr127152.c 
b/gcc/testsuite/gcc.dg/vect/vect-pr127152.c
new file mode 100644
index 00000000000..4b9a599ff0d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-pr127152.c
@@ -0,0 +1,29 @@
+/* { dg-additional-options "--param vect-partial-vector-usage=0" } */
+/* { dg-additional-options "-march=armv8-a+sve" { target aarch64-*-* } } */
+
+#include "tree-vect.h"
+
+__attribute__((noipa)) float
+f (float *a, int n)
+{
+  float s = 0.0f;
+  for (int i = 0; i < n; i++)
+    if (a[i] > 0.0f)
+      s += a[i];
+  return s;
+}
+
+int
+main (void)
+{
+  float a[16];
+
+  check_vect ();
+
+#pragma GCC novector
+  for (int i = 0; i < 16; i++)
+    a[i] = (i & 1) ? 1.0f : -1.0f;
+  if (f (a, 16) != 8.0f)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index e2636c5b767..78f84c6269a 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -7992,9 +7992,9 @@ vect_transform_reduction (loop_vec_info loop_vinfo,
      assumption is not true: we use reduc_index to record the index of the
      reduction variable.  */
   int reduc_index = SLP_TREE_REDUC_IDX (slp_node);
-  slp_tree node_in = SLP_TREE_CHILDREN (slp_node)[reduc_index == 0 ? 1 : 0];
-  tree vectype_in = SLP_TREE_VECTYPE (node_in);
-  unsigned vec_in_num = SLP_TREE_VEC_DEFS (node_in).length ();
+  tree vectype_in = SLP_TREE_VECTYPE (slp_node);
+  if (lane_reducing_op_p (op.code))
+    vectype_in = SLP_TREE_VECTYPE (SLP_TREE_CHILDREN (slp_node)[0]);
 
   code_helper code = canonicalize_code (op.code, op.type);
   internal_fn cond_fn
@@ -8085,6 +8085,7 @@ vect_transform_reduction (loop_vec_info loop_vinfo,
 
   /* For single def-use cycles get one copy of the vectorized reduction
      definition.  */
+  unsigned vec_in_num = vec_oprnds[reduc_index == 0 ? 1 : 0].length ();
   if (single_defuse_cycle)
     {
       vect_get_vec_defs (loop_vinfo, slp_node,
-- 
2.51.0

Reply via email to