This PR shows we have stale reduction groups lying around because the fixup doesn't work reliably with reduction chains. Fixed by delaying the build to after detection is successful.
Bootstrap & regtest running on x86_64-unknown-linux-gnu. Richard. 2018-11-13 Richard Biener <rguent...@suse.de> PR tree-optimization/86991 * tree-vect-loop.c (vect_is_slp_reduction): Delay reduction group building until we have successfully detected the SLP reduction. (vect_is_simple_reduction): Remove fixup code here. * gcc.dg/pr86991.c: New testcase. Index: gcc/tree-vect-loop.c =================================================================== --- gcc/tree-vect-loop.c (revision 266071) +++ gcc/tree-vect-loop.c (working copy) @@ -2476,6 +2476,7 @@ vect_is_slp_reduction (loop_vec_info loo if (loop != vect_loop) return false; + auto_vec<stmt_vec_info, 8> reduc_chain; lhs = PHI_RESULT (phi); code = gimple_assign_rhs_code (first_stmt); while (1) @@ -2528,17 +2529,9 @@ vect_is_slp_reduction (loop_vec_info loo /* Insert USE_STMT into reduction chain. */ use_stmt_info = loop_info->lookup_stmt (loop_use_stmt); - if (current_stmt_info) - { - REDUC_GROUP_NEXT_ELEMENT (current_stmt_info) = use_stmt_info; - REDUC_GROUP_FIRST_ELEMENT (use_stmt_info) - = REDUC_GROUP_FIRST_ELEMENT (current_stmt_info); - } - else - REDUC_GROUP_FIRST_ELEMENT (use_stmt_info) = use_stmt_info; + reduc_chain.safe_push (use_stmt_info); lhs = gimple_assign_lhs (loop_use_stmt); - current_stmt_info = use_stmt_info; size++; } @@ -2548,10 +2541,9 @@ vect_is_slp_reduction (loop_vec_info loo /* Swap the operands, if needed, to make the reduction operand be the second operand. */ lhs = PHI_RESULT (phi); - stmt_vec_info next_stmt_info = REDUC_GROUP_FIRST_ELEMENT (current_stmt_info); - while (next_stmt_info) + for (unsigned i = 0; i < reduc_chain.length (); ++i) { - gassign *next_stmt = as_a <gassign *> (next_stmt_info->stmt); + gassign *next_stmt = as_a <gassign *> (reduc_chain[i]->stmt); if (gimple_assign_rhs2 (next_stmt) == lhs) { tree op = gimple_assign_rhs1 (next_stmt); @@ -2565,7 +2557,6 @@ vect_is_slp_reduction (loop_vec_info loo && vect_valid_reduction_input_p (def_stmt_info)) { lhs = gimple_assign_lhs (next_stmt); - next_stmt_info = REDUC_GROUP_NEXT_ELEMENT (next_stmt_info); continue; } @@ -2600,9 +2591,16 @@ vect_is_slp_reduction (loop_vec_info loo } lhs = gimple_assign_lhs (next_stmt); - next_stmt_info = REDUC_GROUP_NEXT_ELEMENT (next_stmt_info); } + /* Build up the actual chain. */ + for (unsigned i = 0; i < reduc_chain.length () - 1; ++i) + { + REDUC_GROUP_FIRST_ELEMENT (reduc_chain[i]) = reduc_chain[0]; + REDUC_GROUP_NEXT_ELEMENT (reduc_chain[i]) = reduc_chain[i+1]; + } + REDUC_GROUP_NEXT_ELEMENT (reduc_chain.last ()) = NULL; + /* Save the chain for further analysis in SLP detection. */ stmt_vec_info first_stmt_info = REDUC_GROUP_FIRST_ELEMENT (current_stmt_info); @@ -3182,16 +3196,6 @@ vect_is_simple_reduction (loop_vec_info return def_stmt_info; } - /* Dissolve group eventually half-built by vect_is_slp_reduction. */ - stmt_vec_info first = REDUC_GROUP_FIRST_ELEMENT (def_stmt_info); - while (first) - { - stmt_vec_info next = REDUC_GROUP_NEXT_ELEMENT (first); - REDUC_GROUP_FIRST_ELEMENT (first) = NULL; - REDUC_GROUP_NEXT_ELEMENT (first) = NULL; - first = next; - } - /* Look for the expression computing loop_arg from loop PHI result. */ if (check_reduction_path (vect_location, loop, phi, loop_arg, code)) return def_stmt_info; Index: gcc/testsuite/gcc.dg/pr86991.c =================================================================== --- gcc/testsuite/gcc.dg/pr86991.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr86991.c (working copy) @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +int b; +extern unsigned c[]; +unsigned d; +long e; + +void f() +{ + unsigned g, h; + for (; d; d += 2) { + g = 1; + for (; g; g += 3) { + h = 2; + for (; h < 6; h++) + c[h] = c[h] - b - ~e; + } + } +}