diff options
author | Richard Biener <rguenther@suse.de> | 2017-07-27 13:46:07 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2017-07-27 13:46:07 +0000 |
commit | b7675b592316cd5c2a972cb25c714fe85ec743c1 (patch) | |
tree | 0a9f661b70c26d76e9840eed4e2be1147628c826 /gcc/tree-vect-loop.c | |
parent | 719488f819ceb7e7185bf324f04aa9030ba9c2ad (diff) | |
download | gcc-b7675b592316cd5c2a972cb25c714fe85ec743c1.zip gcc-b7675b592316cd5c2a972cb25c714fe85ec743c1.tar.gz gcc-b7675b592316cd5c2a972cb25c714fe85ec743c1.tar.bz2 |
re PR tree-optimization/81573 (wrong code at -O3 on x86_64-linux-gnu)
2017-07-27 Richard Biener <rguenther@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.
From-SVN: r250627
Diffstat (limited to 'gcc/tree-vect-loop.c')
-rw-r--r-- | gcc/tree-vect-loop.c | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 5b1b8a1..8740a75 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -4787,20 +4787,17 @@ vect_create_epilog_for_reduction (vec<tree> 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<tree> 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]); |