aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-sccvn.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2011-01-21 14:02:41 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2011-01-21 14:02:41 +0000
commit3bc27de7f15eb376eaff150d5f5f663bb06426d4 (patch)
treebb89c6b2d21b401a229d25af78bc12f6947a86fa /gcc/tree-ssa-sccvn.c
parent33e39b66855b799d048a88a6a7eaef6d2225c21f (diff)
downloadgcc-3bc27de7f15eb376eaff150d5f5f663bb06426d4.zip
gcc-3bc27de7f15eb376eaff150d5f5f663bb06426d4.tar.gz
gcc-3bc27de7f15eb376eaff150d5f5f663bb06426d4.tar.bz2
re PR tree-optimization/47365 (wrong code with -O -ftree-pre)
2011-01-21 Richard Guenther <rguenther@suse.de> PR tree-optimization/47365 * tree-ssa-sccvn.h (vn_lookup_kind): Declare. (vn_reference_lookup_pieces): Adjust. (vn_reference_lookup): Likewise. * tree-ssa-sccvn.c (vn_walk_kind): New static global. (vn_reference_lookup_3): Only look through kills if in VN_WALKREWRITE mode. (vn_reference_lookup_pieces): Adjust. (vn_reference_lookup): Likewise. (visit_reference_op_load): Likewise. (visit_reference_op_store): Likewise. * tree-ssa-pre.c (phi_translate_1): Use VN_WALK mode. (compute_avail): Likewise. (eliminate): Likewise. * gcc.dg/torture/pr47365.c: New testcase. * gcc.dg/tree-ssa/pr47392.c: Likewise. From-SVN: r169089
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r--gcc/tree-ssa-sccvn.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 970f2c0..e37668e 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1243,6 +1243,7 @@ vn_reference_lookup_1 (vn_reference_t vr, vn_reference_t *vnresult)
}
static tree *last_vuse_ptr;
+static vn_lookup_kind vn_walk_kind;
/* Callback for walk_non_aliased_vuses. Adjusts the vn_reference_t VR_
with the current VUSE and performs the expression lookup. */
@@ -1379,7 +1380,8 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_)
/* For aggregate copies translate the reference through them if
the copy kills ref. */
- else if (gimple_assign_single_p (def_stmt)
+ else if (vn_walk_kind == VN_WALKREWRITE
+ && gimple_assign_single_p (def_stmt)
&& (DECL_P (gimple_assign_rhs1 (def_stmt))
|| TREE_CODE (gimple_assign_rhs1 (def_stmt)) == MEM_REF
|| handled_component_p (gimple_assign_rhs1 (def_stmt))))
@@ -1473,7 +1475,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_)
tree
vn_reference_lookup_pieces (tree vuse, alias_set_type set, tree type,
VEC (vn_reference_op_s, heap) *operands,
- vn_reference_t *vnresult, bool maywalk)
+ vn_reference_t *vnresult, vn_lookup_kind kind)
{
struct vn_reference_s vr1;
vn_reference_t tmp;
@@ -1501,10 +1503,11 @@ vn_reference_lookup_pieces (tree vuse, alias_set_type set, tree type,
vn_reference_lookup_1 (&vr1, vnresult);
if (!*vnresult
- && maywalk
+ && kind != VN_NOWALK
&& vr1.vuse)
{
ao_ref r;
+ vn_walk_kind = kind;
if (ao_ref_init_from_vn_reference (&r, set, type, vr1.operands))
*vnresult =
(vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse,
@@ -1527,7 +1530,7 @@ vn_reference_lookup_pieces (tree vuse, alias_set_type set, tree type,
stored in the hashtable if one exists. */
tree
-vn_reference_lookup (tree op, tree vuse, bool maywalk,
+vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
vn_reference_t *vnresult)
{
VEC (vn_reference_op_s, heap) *operands;
@@ -1545,12 +1548,13 @@ vn_reference_lookup (tree op, tree vuse, bool maywalk,
if ((cst = fully_constant_vn_reference_p (&vr1)))
return cst;
- if (maywalk
+ if (kind != VN_NOWALK
&& vr1.vuse)
{
vn_reference_t wvnresult;
ao_ref r;
ao_ref_init (&r, op);
+ vn_walk_kind = kind;
wvnresult =
(vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse,
vn_reference_lookup_2,
@@ -2257,14 +2261,14 @@ visit_reference_op_load (tree lhs, tree op, gimple stmt)
last_vuse = gimple_vuse (stmt);
last_vuse_ptr = &last_vuse;
- result = vn_reference_lookup (op, gimple_vuse (stmt), true, NULL);
+ result = vn_reference_lookup (op, gimple_vuse (stmt), VN_WALKREWRITE, NULL);
last_vuse_ptr = NULL;
/* If we have a VCE, try looking up its operand as it might be stored in
a different type. */
if (!result && TREE_CODE (op) == VIEW_CONVERT_EXPR)
result = vn_reference_lookup (TREE_OPERAND (op, 0), gimple_vuse (stmt),
- true, NULL);
+ VN_WALKREWRITE, NULL);
/* We handle type-punning through unions by value-numbering based
on offset and size of the access. Be prepared to handle a
@@ -2375,7 +2379,7 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt)
Otherwise, the vdefs for the store are used when inserting into
the table, since the store generates a new memory state. */
- result = vn_reference_lookup (lhs, gimple_vuse (stmt), false, NULL);
+ result = vn_reference_lookup (lhs, gimple_vuse (stmt), VN_NOWALK, NULL);
if (result)
{