The SLP reduc-index computation is confused by having an outer reduction
inner loop nested cycle fed by another non-reduction nested cycle.
Instead of undoing the unfortunate mixing of outer reduction inner
cycles with general nested cycles the following instead distinguishes
them by not setting STMT_VINFO_REDUC_DEF on the non-reduction nested
cycles.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

        PR tree-optimization/121830
        * tree-vect-loop.cc (vect_analyze_scalar_cycles_1): Only
        set STMT_VINFO_REDUC_DEF on reductions.
        * tree-vect-slp.cc (vect_build_slp_tree_2): Identify reduction
        PHIs by a set STMT_VINFO_REDUC_DEF instead of their def type.

        * gcc.dg/vect/pr121830.c: New testcase.
---
 gcc/testsuite/gcc.dg/vect/pr121830.c | 13 +++++++++++++
 gcc/tree-vect-loop.cc                |  4 ++--
 gcc/tree-vect-slp.cc                 |  2 +-
 3 files changed, 16 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/pr121830.c

diff --git a/gcc/testsuite/gcc.dg/vect/pr121830.c 
b/gcc/testsuite/gcc.dg/vect/pr121830.c
new file mode 100644
index 00000000000..7a6ea94ad59
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr121830.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+int a, b;
+short c;
+short d(short e) { return e - 1; }
+int main() {
+  for (; c; c++)
+    for (a = 2; a != 0; a = d(a)) {
+      int *i = &b;
+      *i &= a;
+    }
+  return 0;
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index ed11d1f229a..93f4f1ddd0b 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -460,8 +460,6 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, 
class loop *loop,
        }
       else if (reduc_stmt_info)
        {
-         STMT_VINFO_REDUC_DEF (stmt_vinfo) = reduc_stmt_info;
-         STMT_VINFO_REDUC_DEF (reduc_stmt_info) = stmt_vinfo;
          if (loop != LOOP_VINFO_LOOP (loop_vinfo))
            {
              if (dump_enabled_p ())
@@ -472,6 +470,8 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, 
class loop *loop,
            }
          else
            {
+             STMT_VINFO_REDUC_DEF (stmt_vinfo) = reduc_stmt_info;
+             STMT_VINFO_REDUC_DEF (reduc_stmt_info) = stmt_vinfo;
              if (dump_enabled_p ())
                dump_printf_loc (MSG_NOTE, vect_location,
                                 "Detected reduction.\n");
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index 6258a8eb53d..b06b67e283e 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -2832,7 +2832,7 @@ out:
 
       /* See which SLP operand a reduction chain continues on.  We want
         to chain even PHIs but not backedges.  */
-      if (VECTORIZABLE_CYCLE_DEF (oprnd_info->first_dt)
+      if (STMT_VINFO_REDUC_DEF (oprnd_info->def_stmts[0])
          || STMT_VINFO_REDUC_IDX (oprnd_info->def_stmts[0]) != -1)
        {
          if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle)
-- 
2.43.0

Reply via email to