File pr35472.diff of Package gcc43
2008-03-05 Richard Guenther <rguenther@suse.de>
PR tree-optimization/35472
* tree-ssa-dse.c (dse_optimize_stmt): Do not delete a store
whose single use_stmt has a overlapping set of loaded and
stored symbols as that use_stmt might be a noop assignment then.
* gcc.c-torture/execute/pr35472.c: New testcase.
Index: gcc/tree-ssa-dse.c
===================================================================
*** gcc/tree-ssa-dse.c (revision 132896)
--- gcc/tree-ssa-dse.c (working copy)
*************** dse_optimize_stmt (struct dom_walk_data
*** 470,493 ****
vuse_vec_p vv;
tree stmt_lhs;
! if (LOADED_SYMS (use_stmt))
{
! tree use_base
! = get_base_address (GIMPLE_STMT_OPERAND (use_stmt, 0));
! /* If use_stmt is or might be a nop assignment, e.g. for
! struct { ... } S a, b, *p; ...
! b = a; b = b;
! or
! b = a; b = *p; where p might be &b, then USE_STMT
! acts as a use as well as definition, so store in STMT
! is not dead. */
! if (TREE_CODE (use_base) == VAR_DECL
! && bitmap_bit_p (LOADED_SYMS (use_stmt),
! DECL_UID (use_base)))
! {
! record_voperand_set (dse_gd->stores, &bd->stores, ann->uid);
! return;
! }
}
if (dump_file && (dump_flags & TDF_DETAILS))
--- 470,492 ----
vuse_vec_p vv;
tree stmt_lhs;
! /* If use_stmt is or might be a nop assignment, e.g. for
! struct { ... } S a, b, *p; ...
! b = a; b = b;
! or
! b = a; b = *p; where p might be &b,
! or
! *p = a; *p = b; where p might be &b,
! or
! *p = *u; *p = *v; where p might be v, then USE_STMT
! acts as a use as well as definition, so store in STMT
! is not dead. */
! if (LOADED_SYMS (use_stmt)
! && bitmap_intersect_p (LOADED_SYMS (use_stmt),
! STORED_SYMS (use_stmt)))
{
! record_voperand_set (dse_gd->stores, &bd->stores, ann->uid);
! return;
}
if (dump_file && (dump_flags & TDF_DETAILS))
Index: gcc/testsuite/gcc.c-torture/execute/pr35472.c
===================================================================
*** gcc/testsuite/gcc.c-torture/execute/pr35472.c (revision 0)
--- gcc/testsuite/gcc.c-torture/execute/pr35472.c (revision 0)
***************
*** 0 ****
--- 1,22 ----
+ extern void abort (void);
+ extern void *memset (void *s, int c, __SIZE_TYPE__ n);
+ struct S { int i[16]; };
+ struct S *p;
+ void __attribute__((noinline))
+ foo(struct S *a, struct S *b) { a->i[0] = -1; p = b; }
+ void test (void)
+ {
+ struct S a, b;
+ memset (&a.i[0], '\0', sizeof (a.i));
+ memset (&b.i[0], '\0', sizeof (b.i));
+ foo (&a, &b);
+ *p = a;
+ *p = b;
+ if (b.i[0] != -1)
+ abort ();
+ }
+ int main()
+ {
+ test();
+ return 0;
+ }