[PATCH] Fix PR35472, wrong-code with DSE (again)
Richard Guenther
rguenther@suse.de
Wed Mar 5 15:07:00 GMT 2008
So we missed some cases in the fix for PR34459, and the issue is
masked for the testcase for that PR because of PR27799. Still
I had a one that triggers.
So the failure mode is that DSE removes a store because there is
a noop store following. Which is of course bad and exactly the
failure mode of PR34459. The real fix is to punt if there is
any overlap in the LOADED/STORED syms of the use shadowing the
store, as it then possibly can be a noop store (it could even
look like *p = *q, not exposing a symbol directly).
Bootstrap and regtest running on x86_64-unknown-linux-gnu.
Richard.
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: tree-ssa-dse.c
===================================================================
*** tree-ssa-dse.c (revision 132896)
--- 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: testsuite/gcc.c-torture/execute/pr35472.c
===================================================================
*** testsuite/gcc.c-torture/execute/pr35472.c (revision 0)
--- 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;
+ }
More information about the Gcc-patches
mailing list