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
This commit is contained in:
Richard Guenther 2011-01-21 14:02:41 +00:00 committed by Richard Biener
parent 33e39b6685
commit 3bc27de7f1
7 changed files with 143 additions and 18 deletions

View File

@ -1,3 +1,20 @@
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.
2011-01-21 Jakub Jelinek <jakub@redhat.com>
* tree-ssa-live.c (remove_unused_scope_block_p): Don't remove

View File

@ -1,3 +1,9 @@
2011-01-21 Richard Guenther <rguenther@suse.de>
PR tree-optimization/47365
* gcc.dg/torture/pr47365.c: New testcase.
* gcc.dg/tree-ssa/pr47392.c: Likewise.
2011-01-21 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* g++.dg/other/anon5.C: Skip on mips-sgi-irix*.

View File

@ -0,0 +1,39 @@
/* { dg-do run } */
struct A
{
int i;
};
struct B
{
struct A a[2];
};
int i = 1;
struct B b = { 0, 3 };
static void
test ()
{
if (b.a[0].i != i)
{
int t = b.a[0].i;
b.a[0] = b.a[1];
b.a[1].i = t;
}
if (b.a[1].i == i)
__builtin_abort ();
if (b.a[0].i == 0)
__builtin_abort ();
}
int
main ()
{
test ();
return 0;
}

View File

@ -0,0 +1,42 @@
/* { dg-do run } */
/* { dg-options "-O2 -fdump-tree-pre-stats" } */
struct A
{
int i;
};
struct B
{
struct A a[2];
};
int i = 1;
struct B b = { 0, 3 };
static void
test ()
{
if (b.a[0].i != i)
{
int t = b.a[0].i;
b.a[0] = b.a[1];
b.a[1].i = t;
}
if (b.a[1].i == i)
__builtin_abort ();
if (b.a[0].i == 0)
__builtin_abort ();
}
int __attribute__((hot))
main ()
{
test ();
return 0;
}
/* { dg-final { scan-tree-dump "Eliminated: 1" "pre" } } */
/* { dg-final { cleanup-tree-dump "pre" } } */

View File

@ -1681,7 +1681,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
tree result = vn_reference_lookup_pieces (newvuse, ref->set,
ref->type,
newoperands,
&newref, true);
&newref, VN_WALK);
if (result)
VEC_free (vn_reference_op_s, heap, newoperands);
@ -2594,6 +2594,10 @@ compute_antic (void)
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Starting iteration %d\n", num_iterations);
/* ??? We need to clear our PHI translation cache here as the
ANTIC sets shrink and we restrict valid translations to
those having operands with leaders in ANTIC. Same below
for PA ANTIC computation. */
num_iterations++;
changed = false;
for (i = n_basic_blocks - NUM_FIXED_BLOCKS - 1; i >= 0; i--)
@ -3607,11 +3611,23 @@ do_regular_insertion (basic_block block, basic_block dom)
already existing along every predecessor, and
it's defined by some predecessor, it is
partially redundant. */
if (!cant_insert && !all_same && by_some && do_insertion
&& dbg_cnt (treepre_insert))
if (!cant_insert && !all_same && by_some)
{
if (insert_into_preds_of_block (block, get_expression_id (expr),
avail))
if (!do_insertion)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Skipping partial redundancy for "
"expression ");
print_pre_expr (dump_file, expr);
fprintf (dump_file, " (%04d), no redundancy on to be "
"optimized for speed edge\n", val);
}
}
else if (dbg_cnt (treepre_insert)
&& insert_into_preds_of_block (block,
get_expression_id (expr),
avail))
new_stuff = true;
}
/* If all edges produce the same value and that value is
@ -3999,7 +4015,7 @@ compute_avail (void)
copy_reference_ops_from_call (stmt, &ops);
vn_reference_lookup_pieces (gimple_vuse (stmt), 0,
gimple_expr_type (stmt),
ops, &ref, false);
ops, &ref, VN_NOWALK);
VEC_free (vn_reference_op_s, heap, ops);
if (!ref)
continue;
@ -4069,7 +4085,7 @@ compute_avail (void)
vn_reference_lookup (gimple_assign_rhs1 (stmt),
gimple_vuse (stmt),
true, &ref);
VN_WALK, &ref);
if (!ref)
continue;
@ -4313,7 +4329,7 @@ eliminate (void)
tree rhs = gimple_assign_rhs1 (stmt);
tree val;
val = vn_reference_lookup (gimple_assign_lhs (stmt),
gimple_vuse (stmt), true, NULL);
gimple_vuse (stmt), VN_WALK, NULL);
if (TREE_CODE (rhs) == SSA_NAME)
rhs = VN_INFO (rhs)->valnum;
if (val

View File

@ -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)
{

View File

@ -187,10 +187,11 @@ void copy_reference_ops_from_ref (tree, VEC(vn_reference_op_s, heap) **);
void copy_reference_ops_from_call (gimple, VEC(vn_reference_op_s, heap) **);
bool ao_ref_init_from_vn_reference (ao_ref *, alias_set_type, tree,
VEC (vn_reference_op_s, heap) *);
typedef enum { VN_NOWALK, VN_WALK, VN_WALKREWRITE } vn_lookup_kind;
tree vn_reference_lookup_pieces (tree, alias_set_type, tree,
VEC (vn_reference_op_s, heap) *,
vn_reference_t *, bool);
tree vn_reference_lookup (tree, tree, bool, vn_reference_t *);
vn_reference_t *, vn_lookup_kind);
tree vn_reference_lookup (tree, tree, vn_lookup_kind, vn_reference_t *);
vn_reference_t vn_reference_insert (tree, tree, tree);
vn_reference_t vn_reference_insert_pieces (tree, alias_set_type, tree,
VEC (vn_reference_op_s, heap) *,