This fixes PR57488 - clearing NEW sets before each insert iteration ensures we don't propagate memory accesses across back-edges into regions where that would not be valid.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2013-06-24 Richard Biener <rguent...@suse.de> PR tree-optimization/57488 * tree-ssa-pre.c (insert): Clear NEW sets before each iteration. * gcc.dg/torture/pr57488.c: New testcase. Index: gcc/tree-ssa-pre.c =================================================================== *** gcc/tree-ssa-pre.c (revision 200237) --- gcc/tree-ssa-pre.c (working copy) *************** insert (void) *** 3665,3670 **** --- 3666,3677 ---- if (dump_file && dump_flags & TDF_DETAILS) fprintf (dump_file, "Starting insert iteration %d\n", num_iterations); new_stuff = insert_aux (ENTRY_BLOCK_PTR); + + /* Clear the NEW sets before the next iteration. We have already + fully propagated its contents. */ + if (new_stuff) + FOR_ALL_BB (bb) + bitmap_set_free (NEW_SETS (bb)); } statistics_histogram_event (cfun, "insert iterations", num_iterations); } Index: gcc/testsuite/gcc.dg/torture/pr57488.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr57488.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr57488.c (working copy) *************** *** 0 **** --- 1,58 ---- + /* { dg-do run } */ + + extern void abort (void); + + int i, j, *pj = &j, **ppj = &pj; + int x, *px = &x; + + short s, *ps = &s, k; + + unsigned short u, *pu = &u, **ppu = &pu; + + char c, *pc = &c; + + unsigned char v = 48; + + static int + bar (int p) + { + p = k; + *px = **ppu = i; + *ppj = &p; + if (**ppj) + *pj = p; + return p; + } + + void __attribute__((noinline)) + foo () + { + for (; i <= 3; i++) + for (; j; j--); + + u ^= bar (*pj); + + for (k = 1; k >= 0; k--) + { + int l; + bar (0); + for (l = 1; l < 5; l++) + { + int m; + for (m = 6; m; m--) + { + v--; + *ps = *pc; + } + } + } + } + + int + main () + { + foo (); + if (v != 0) + abort (); + return 0; + }