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.
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.
--- /dev/null
+/* { 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;
+}
}
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 ())
}
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");
/* 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)