From b7675b592316cd5c2a972cb25c714fe85ec743c1 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 27 Jul 2017 13:46:07 +0000 Subject: [PATCH] re PR tree-optimization/81573 (wrong code at -O3 on x86_64-linux-gnu) 2017-07-27 Richard Biener 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. From-SVN: r250627 --- gcc/ChangeLog | 7 ++++++ gcc/testsuite/ChangeLog | 6 +++++ gcc/testsuite/gcc.dg/torture/pr81573.c | 16 +++++++++++++ gcc/tree-vect-loop.c | 33 ++++++++++++++++++++------ 4 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr81573.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3ae2f46c8f2..77a77ebca7f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-07-27 Richard Biener + + PR tree-optimization/81573 + PR tree-optimization/81494 + * tree-vect-loop.c (vect_create_epilog_for_reduction): Handle + multi defuse cycle case. + 2017-07-27 Richard Biener PR tree-optimization/81571 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e12654400b9..fe0b88c84fe 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2017-07-27 Richard Biener + + PR tree-optimization/81573 + PR tree-optimization/81494 + * gcc.dg/torture/pr81573.c: New testcase. + 2017-07-27 Richard Biener PR tree-optimization/81571 diff --git a/gcc/testsuite/gcc.dg/torture/pr81573.c b/gcc/testsuite/gcc.dg/torture/pr81573.c new file mode 100644 index 00000000000..3f0904aa5ea --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr81573.c @@ -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; +} diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 5b1b8a1fdee..8740a7573ac 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -4787,20 +4787,17 @@ vect_create_epilog_for_reduction (vec vect_defs, gimple *stmt, 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 +4807,28 @@ vect_create_epilog_for_reduction (vec vect_defs, gimple *stmt, 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]); -- 2.30.2