The following fixes PR81573. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.
Richard. 2017-07-27 Richard Biener <rguent...@suse.de> PR tree-optimization/81573 PR tree-optimization/81494 * tree-vect-loop.c (vect_create_epilog_for_reduction): Handle multi defuse cycle case. * gcc.dg/torture/pr81573.c: New testcase. Index: gcc/tree-vect-loop.c =================================================================== --- gcc/tree-vect-loop.c (revision 250607) +++ gcc/tree-vect-loop.c (working copy) @@ -4787,20 +4800,17 @@ vect_create_epilog_for_reduction (vec<tr if (GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt))) { tree first_vect = PHI_RESULT (new_phis[0]); - tree tmp; gassign *new_vec_stmt = NULL; - vec_dest = vect_create_destination_var (scalar_dest, vectype); for (k = 1; k < new_phis.length (); k++) { gimple *next_phi = new_phis[k]; tree second_vect = PHI_RESULT (next_phi); - - tmp = build2 (code, vectype, first_vect, second_vect); - new_vec_stmt = gimple_build_assign (vec_dest, tmp); - first_vect = make_ssa_name (vec_dest, new_vec_stmt); - gimple_assign_set_lhs (new_vec_stmt, first_vect); + tree tem = make_ssa_name (vec_dest, new_vec_stmt); + new_vec_stmt = gimple_build_assign (tem, code, + first_vect, second_vect); gsi_insert_before (&exit_gsi, new_vec_stmt, GSI_SAME_STMT); + first_vect = tem; } new_phi_result = first_vect; @@ -4810,6 +4820,28 @@ vect_create_epilog_for_reduction (vec<tr new_phis.safe_push (new_vec_stmt); } } + /* Likewise if we couldn't use a single defuse cycle. */ + else if (ncopies > 1) + { + gcc_assert (new_phis.length () == 1); + tree first_vect = PHI_RESULT (new_phis[0]); + gassign *new_vec_stmt = NULL; + vec_dest = vect_create_destination_var (scalar_dest, vectype); + gimple *next_phi = new_phis[0]; + for (int k = 1; k < ncopies; ++k) + { + next_phi = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (next_phi)); + tree second_vect = PHI_RESULT (next_phi); + tree tem = make_ssa_name (vec_dest, new_vec_stmt); + new_vec_stmt = gimple_build_assign (tem, code, + first_vect, second_vect); + gsi_insert_before (&exit_gsi, new_vec_stmt, GSI_SAME_STMT); + first_vect = tem; + } + new_phi_result = first_vect; + new_phis.truncate (0); + new_phis.safe_push (new_vec_stmt); + } else new_phi_result = PHI_RESULT (new_phis[0]); Index: gcc/testsuite/gcc.dg/torture/pr81573.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr81573.c (nonexistent) +++ gcc/testsuite/gcc.dg/torture/pr81573.c (working copy) @@ -0,0 +1,16 @@ +/* { dg-do run } */ + +int a = 1, *c = &a, d; +char b; + +int main () +{ + for (; b > -27; b--) + { + *c ^= b; + *c ^= 1; + } + while (a > 1) + ; + return 0; +}