aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-loop-manip.cc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2024-01-19 13:55:09 +0100
committerRichard Biener <rguenther@suse.de>2024-01-22 08:48:26 +0100
commit86f3cbdaa6f60eaff1cdb4ab2f1a9bc796b67207 (patch)
tree702e743b95c9c643df4c16dd2f735212b648c736 /gcc/tree-vect-loop-manip.cc
parenta618b3c65745a6992ced4df60c186241c2da6eae (diff)
downloadgcc-86f3cbdaa6f60eaff1cdb4ab2f1a9bc796b67207.zip
gcc-86f3cbdaa6f60eaff1cdb4ab2f1a9bc796b67207.tar.gz
gcc-86f3cbdaa6f60eaff1cdb4ab2f1a9bc796b67207.tar.bz2
tree-optimization/113373 - add missing LC PHIs for live operations
The following makes reduction epilogue code generation happy by properly adding LC PHIs to the exit blocks for multiple exit vectorized loops. Some refactoring might make the flow easier to follow but I've refrained from doing that with this patch. I've kept some fixes in reduction epilogue generation from the earlier attempt fixing this PR. PR tree-optimization/113373 * tree-vect-loop-manip.cc (slpeel_tree_duplicate_loop_to_edge_cfg): Create LC PHIs in the exit blocks where necessary. * tree-vect-loop.cc (vectorizable_live_operation): Do not try to handle missing LC PHIs. (find_connected_edge): Remove. (vect_create_epilog_for_reduction): Cleanup use of auto_vec. * gcc.dg/vect/vect-early-break_104-pr113373.c: New testcase.
Diffstat (limited to 'gcc/tree-vect-loop-manip.cc')
-rw-r--r--gcc/tree-vect-loop-manip.cc34
1 files changed, 29 insertions, 5 deletions
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index 1477906..eacbc02 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -1696,7 +1696,8 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit,
/* Check if we've already created a new phi node during edge
redirection. If we have, only propagate the value
downwards in case there is no merge block. */
- if (tree *res = new_phi_args.get (new_arg))
+ tree *res;
+ if ((res = new_phi_args.get (new_arg)))
{
if (multiple_exits_p)
new_arg = *res;
@@ -1717,7 +1718,7 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit,
/* Similar to the single exit case, If we have an existing
LCSSA variable thread through the original value otherwise
skip it and directly use the final value. */
- if (tree *res = new_phi_args.get (tmp_arg))
+ if ((res = new_phi_args.get (tmp_arg)))
new_arg = *res;
else if (!virtual_operand_p (new_arg))
new_arg = tmp_arg;
@@ -1728,9 +1729,20 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit,
/* Otherwise, main loop exit should use the final iter value. */
if (multiple_exits_p)
- SET_PHI_ARG_DEF_ON_EDGE (lcssa_phi,
- single_succ_edge (main_loop_exit_block),
- new_arg);
+ {
+ /* Create a LC PHI if it doesn't already exist. */
+ if (!virtual_operand_p (new_arg) && !res)
+ {
+ tree new_def = copy_ssa_name (new_arg);
+ gphi *lc_phi
+ = create_phi_node (new_def, main_loop_exit_block);
+ SET_PHI_ARG_DEF (lc_phi, 0, new_arg);
+ new_arg = new_def;
+ }
+ SET_PHI_ARG_DEF_ON_EDGE (lcssa_phi,
+ single_succ_edge (main_loop_exit_block),
+ new_arg);
+ }
else
SET_PHI_ARG_DEF_ON_EDGE (lcssa_phi, loop_exit, new_arg);
@@ -1766,6 +1778,18 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit,
if (vphi)
alt_arg = gimple_phi_result (vphi);
}
+ /* For other live args we didn't create LC PHI nodes.
+ Do so here. */
+ else
+ {
+ tree alt_def = copy_ssa_name (alt_arg);
+ gphi *lc_phi
+ = create_phi_node (alt_def, alt_loop_exit_block);
+ for (unsigned i = 0; i < gimple_phi_num_args (lc_phi);
+ ++i)
+ SET_PHI_ARG_DEF (lc_phi, i, alt_arg);
+ alt_arg = alt_def;
+ }
edge main_e = single_succ_edge (alt_loop_exit_block);
SET_PHI_ARG_DEF_ON_EDGE (to_phi, main_e, alt_arg);
}