diff options
author | Richard Biener <rguenther@suse.de> | 2018-09-04 10:55:46 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2018-09-04 10:55:46 +0000 |
commit | c2c51a3e358294b5ddfa522fa4d973c3360699b4 (patch) | |
tree | 6f6ecfbfcc692b9233cf702e2437761aa05a4fb8 /gcc/tree-ssa-sccvn.c | |
parent | 727c8c82e14021cad992443bb32693293a55e33d (diff) | |
download | gcc-c2c51a3e358294b5ddfa522fa4d973c3360699b4.zip gcc-c2c51a3e358294b5ddfa522fa4d973c3360699b4.tar.gz gcc-c2c51a3e358294b5ddfa522fa4d973c3360699b4.tar.bz2 |
re PR tree-optimization/87176 (wrong code at -Os and above on x86-64-linux-gnu)
2018-09-04 Richard Biener <rguenther@suse.de>
PR tree-optimization/87176
* tree-ssa-sccvn.c (visit_phi): Remove redundant allsame
variable. When value-numbering a virtual PHI node make sure
to not value-number to the backedge value.
* gcc.dg/torture/pr87176.c: New testcase.
* gcc.dg/torture/ssa-fre-1.c: Likewise.
From-SVN: r264077
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r-- | gcc/tree-ssa-sccvn.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 34c193b..8d68b6b 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -4110,11 +4110,11 @@ 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 backedge_val = NULL_TREE; + bool seen_non_backedge = false; tree sameval_base = NULL_TREE; poly_int64 soff, doff; unsigned n_executable = 0; - bool allsame = true; edge_iterator ei; edge e; @@ -4139,11 +4139,13 @@ visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p) ++n_executable; 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 (e->flags & EDGE_DFS_BACK) + backedge_val = def; } + if (!(e->flags & EDGE_DFS_BACK)) + seen_non_backedge = true; if (def == VN_TOP) ; /* Ignore undefined defs for sameval but record one. */ @@ -4172,16 +4174,25 @@ visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p) && known_eq (soff, doff)) continue; } - allsame = false; + sameval = NULL_TREE; break; } } /* 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)) + yet drop to VARYING. This only happens when not iterating. + If we value-number a virtual operand never value-number to the + value from the backedge as that confuses the alias-walking code. + See gcc.dg/torture/pr87176.c. If the value is the same on a + non-backedge everything is OK though. */ + if (backedge_val + && !seen_non_backedge + && TREE_CODE (backedge_val) == SSA_NAME + && sameval == backedge_val + && (SSA_NAME_IS_VIRTUAL_OPERAND (backedge_val) + || !SSA_VISITED (backedge_val))) + /* Note this just drops to VARYING without inserting the PHI into + the hashes. */ 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. */ @@ -4212,7 +4223,7 @@ visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p) /* If all values are the same use that, unless we've seen undefined values as well and the value isn't constant. CCP/copyprop have the same restriction to not remove uninit warnings. */ - else if (allsame + else if (sameval && (! seen_undef || is_gimple_min_invariant (sameval))) result = sameval; else |