diff options
author | Richard Biener <rguenther@suse.de> | 2021-10-19 10:19:12 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2021-10-19 12:29:33 +0200 |
commit | d996799a507f9f4c379b55b004233be92fa63380 (patch) | |
tree | eca587f2c3ee0c5365f7131853eb6dd6c1f2f8bc /gcc/tree-if-conv.c | |
parent | f98359ba9d3775319fb3181009be7d3dafe9ba15 (diff) | |
download | gcc-d996799a507f9f4c379b55b004233be92fa63380.zip gcc-d996799a507f9f4c379b55b004233be92fa63380.tar.gz gcc-d996799a507f9f4c379b55b004233be92fa63380.tar.bz2 |
tree-optimization/102827 - avoid stmts in preheader
The PR shows that when carefully crafting the runtime alias
condition in the vectorizer we might end up using defs from
the loop preheader but will end up inserting the condition
before the .LOOP_VECTORIZED call. So the following makes
sure to insert invariants before that when we versioned the
loop, preserving the invariant the vectorizer relies on.
2021-10-19 Richard Biener <rguenther@suse.de>
PR tree-optimization/102827
* tree-if-conv.c (predicate_statements): Add pe parameter
and use that edge to insert invariant stmts on.
(combine_blocks): Pass through pe.
(tree_if_conversion): Compute the edge to insert invariant
stmts on and pass it along.
* gcc.dg/pr102827.c: New testcase.
Diffstat (limited to 'gcc/tree-if-conv.c')
-rw-r--r-- | gcc/tree-if-conv.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 15dcc1e..b165dc0 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -2490,7 +2490,7 @@ predicate_rhs_code (gassign *stmt, tree mask, tree cond, */ static void -predicate_statements (loop_p loop) +predicate_statements (loop_p loop, edge pe) { unsigned int i, orig_loop_num_nodes = loop->num_nodes; auto_vec<int, 1> vect_sizes; @@ -2596,8 +2596,7 @@ predicate_statements (loop_p loop) if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt2)) && expr_invariant_in_loop_p (loop, gimple_assign_rhs1 (stmt2))) - gsi_insert_on_edge_immediate (loop_preheader_edge (loop), - stmt2); + gsi_insert_on_edge_immediate (pe, stmt2); else if (first) { gsi_insert_before (&gsi, stmt2, GSI_NEW_STMT); @@ -2679,7 +2678,7 @@ remove_conditions_and_labels (loop_p loop) blocks. Replace PHI nodes with conditional modify expressions. */ static void -combine_blocks (class loop *loop) +combine_blocks (class loop *loop, edge pe) { basic_block bb, exit_bb, merge_target_bb; unsigned int orig_loop_num_nodes = loop->num_nodes; @@ -2692,7 +2691,7 @@ combine_blocks (class loop *loop) predicate_all_scalar_phis (loop); if (need_to_predicate || need_to_rewrite_undefined) - predicate_statements (loop); + predicate_statements (loop, pe); /* Merge basic blocks. */ exit_bb = NULL; @@ -3187,6 +3186,7 @@ tree_if_conversion (class loop *loop, vec<gimple *> *preds) bool aggressive_if_conv; class loop *rloop; bitmap exit_bbs; + edge pe; again: rloop = NULL; @@ -3218,6 +3218,9 @@ tree_if_conversion (class loop *loop, vec<gimple *> *preds) || loop->dont_vectorize)) goto cleanup; + /* The edge to insert invariant stmts on. */ + pe = loop_preheader_edge (loop); + /* Since we have no cost model, always version loops unless the user specified -ftree-loop-if-convert or unless versioning is required. Either version this loop, or if the pattern is right for outer-loop @@ -3255,12 +3258,18 @@ tree_if_conversion (class loop *loop, vec<gimple *> *preds) gcc_assert (nloop->inner && nloop->inner->next == NULL); rloop = nloop->inner; } + else + /* If we versioned loop then make sure to insert invariant + stmts before the .LOOP_VECTORIZED check since the vectorizer + will re-use that for things like runtime alias versioning + whose condition can end up using those invariants. */ + pe = single_pred_edge (gimple_bb (preds->last ())); } /* Now all statements are if-convertible. Combine all the basic blocks into one huge basic block doing the if-conversion on-the-fly. */ - combine_blocks (loop); + combine_blocks (loop, pe); /* Perform local CSE, this esp. helps the vectorizer analysis if loads and stores are involved. CSE only the loop body, not the entry |