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