aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-if-conv.cc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-12-12 14:01:47 +0100
committerRichard Biener <rguenther@suse.de>2023-12-12 15:13:15 +0100
commit878cb5acf0c499702ffd315e273f55e8bd0970b8 (patch)
tree07d35ca985dce2f1cca214fbd366b2161bc76c66 /gcc/tree-if-conv.cc
parentdabd94da0c78f4beb0c2c25f38ab6de2d8417497 (diff)
downloadgcc-878cb5acf0c499702ffd315e273f55e8bd0970b8.zip
gcc-878cb5acf0c499702ffd315e273f55e8bd0970b8.tar.gz
gcc-878cb5acf0c499702ffd315e273f55e8bd0970b8.tar.bz2
tree-optimization/112961 - include latch in if-conversion CSE
The following makes sure to also process the (empty) latch when performing CSE on the if-converted loop body. That's important to get all uses of copies propagated out on the backedge as well. To avoid CSE on the PHI nodes itself which is prohibitive (see PR90402) this temporarily adds a fake entry edge to the loop. PR tree-optimization/112961 * tree-if-conv.cc (tree_if_conversion): Instead of excluding the latch block from VN, add a fake entry edge. * g++.dg/vect/pr112961.cc: New testcase.
Diffstat (limited to 'gcc/tree-if-conv.cc')
-rw-r--r--gcc/tree-if-conv.cc9
1 files changed, 7 insertions, 2 deletions
diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc
index 0bde281..f9fd014 100644
--- a/gcc/tree-if-conv.cc
+++ b/gcc/tree-if-conv.cc
@@ -3734,7 +3734,7 @@ tree_if_conversion (class loop *loop, vec<gimple *> *preds)
auto_vec <gassign *, 4> reads_to_lower;
auto_vec <gassign *, 4> writes_to_lower;
bitmap exit_bbs;
- edge pe;
+ edge pe, e;
auto_vec<data_reference_p, 10> refs;
bool loop_versioned;
@@ -3894,11 +3894,13 @@ tree_if_conversion (class loop *loop, vec<gimple *> *preds)
/* Perform local CSE, this esp. helps the vectorizer analysis if loads
and stores are involved. CSE only the loop body, not the entry
PHIs, those are to be kept in sync with the non-if-converted copy.
+ Do this by adding a fake entry edge - we do want to include the
+ latch as otherwise copies on a reduction path cannot be propagated out.
??? We'll still keep dead stores though. */
+ e = make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), loop->header, EDGE_FAKE);
exit_bbs = BITMAP_ALLOC (NULL);
for (edge exit : get_loop_exit_edges (loop))
bitmap_set_bit (exit_bbs, exit->dest->index);
- bitmap_set_bit (exit_bbs, loop->latch->index);
std::pair <tree, tree> *name_pair;
unsigned ssa_names_idx;
@@ -3908,6 +3910,9 @@ tree_if_conversion (class loop *loop, vec<gimple *> *preds)
todo |= do_rpo_vn (cfun, loop_preheader_edge (loop), exit_bbs);
+ /* Remove the fake edge again. */
+ remove_edge (e);
+
/* Delete dead predicate computations. */
ifcvt_local_dce (loop);
BITMAP_FREE (exit_bbs);