diff options
author | Richard Biener <rguenther@suse.de> | 2018-08-30 12:37:10 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2018-08-30 12:37:10 +0000 |
commit | b1d5f644929182de05cf2bb940a6c417ec28f29a (patch) | |
tree | e9f0db5db8d2a0fdf340469bc42a7d577979b988 /gcc/tree-ssa-sccvn.c | |
parent | 28428506aafe4613e4abf0b38671b4fc9c371ef9 (diff) | |
download | gcc-b1d5f644929182de05cf2bb940a6c417ec28f29a.zip gcc-b1d5f644929182de05cf2bb940a6c417ec28f29a.tar.gz gcc-b1d5f644929182de05cf2bb940a6c417ec28f29a.tar.bz2 |
re PR tree-optimization/87147 (GCC miscompiles at -O3 on valid code)
2018-08-30 Richard Biener <rguenther@suse.de>
PR tree-optimization/87147
* tree-ssa-sccvn.c (SSA_VISITED): New function.
(visit_phi): When the degenerate result is from the backedge and
we didn't visit its definition yet drop to VARYING.
(do_rpo_vn): Properly mark blocks with incoming backedges as executable.
* gcc.dg/torture/pr87147.c: New testcase.
From-SVN: r263980
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r-- | gcc/tree-ssa-sccvn.c | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 39ab4b2..2bf71e5 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -462,6 +462,15 @@ SSA_VAL (tree x) return tem && tem->visited ? tem->valnum : x; } +/* Return whether X was visited. */ + +inline bool +SSA_VISITED (tree x) +{ + vn_ssa_aux_t tem = vn_ssa_aux_hash->find_with_hash (x, SSA_NAME_VERSION (x)); + return tem && tem->visited; +} + /* Return the SSA value of the VUSE x, supporting released VDEFs during elimination which will value-number the VDEF to the associated VUSE (but not substitute in the whole lattice). */ @@ -4100,6 +4109,7 @@ static bool visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p) { tree result, sameval = VN_TOP, seen_undef = NULL_TREE; + tree backedge_name = NULL_TREE; tree sameval_base = NULL_TREE; poly_int64 soff, doff; unsigned n_executable = 0; @@ -4126,9 +4136,13 @@ visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p) tree def = PHI_ARG_DEF_FROM_EDGE (phi, e); ++n_executable; - if (TREE_CODE (def) == SSA_NAME - && (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK))) - def = SSA_VAL (def); + if (TREE_CODE (def) == SSA_NAME) + { + if (e->flags & EDGE_DFS_BACK) + backedge_name = def; + if (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK)) + def = SSA_VAL (def); + } if (def == VN_TOP) ; /* Ignore undefined defs for sameval but record one. */ @@ -4162,10 +4176,15 @@ visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p) } } - + /* If the value we want to use is the backedge and that wasn't visited + yet drop to VARYING. */ + if (backedge_name + && sameval == backedge_name + && !SSA_VISITED (backedge_name)) + result = PHI_RESULT (phi); /* If none of the edges was executable keep the value-number at VN_TOP, if only a single edge is exectuable use its value. */ - if (n_executable <= 1) + else if (n_executable <= 1) result = seen_undef ? seen_undef : sameval; /* If we saw only undefined values and VN_TOP use one of the undefined values. */ @@ -6298,6 +6317,7 @@ do_rpo_vn (function *fn, edge entry, bitmap exit_bbs, { basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]); rpo_state[i].visited = 0; + bb->flags &= ~BB_EXECUTABLE; bool has_backedges = false; edge e; edge_iterator ei; @@ -6306,12 +6326,17 @@ do_rpo_vn (function *fn, edge entry, bitmap exit_bbs, if (e->flags & EDGE_DFS_BACK) has_backedges = true; if (! iterate && (e->flags & EDGE_DFS_BACK)) - e->flags |= EDGE_EXECUTABLE; + { + e->flags |= EDGE_EXECUTABLE; + /* ??? Strictly speaking we only need to unconditionally + process a block when it is in an irreducible region, + thus when it may be reachable via the backedge only. */ + bb->flags |= BB_EXECUTABLE; + } else e->flags &= ~EDGE_EXECUTABLE; } rpo_state[i].iterate = iterate && has_backedges; - bb->flags &= ~BB_EXECUTABLE; } entry->flags |= EDGE_EXECUTABLE; entry->dest->flags |= BB_EXECUTABLE; |