aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-sccvn.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2018-09-04 10:55:46 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2018-09-04 10:55:46 +0000
commitc2c51a3e358294b5ddfa522fa4d973c3360699b4 (patch)
tree6f6ecfbfcc692b9233cf702e2437761aa05a4fb8 /gcc/tree-ssa-sccvn.c
parent727c8c82e14021cad992443bb32693293a55e33d (diff)
downloadgcc-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.c31
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