The following avoids speculating loads in phiprop (sth it was never supposed to do). That fixes the crashes in the PR.
Bootstrap and regtest ongoing on x86_64-unknown-linux-gnu. Richard. 2014-02-14 Richard Biener <rguent...@suse.de> PR tree-optimization/60183 * tree-ssa-phiprop.c (propagate_with_phi): Avoid speculating loads. (tree_ssa_phiprop): Calculate and free post-dominators. * gcc.dg/torture/pr60183.c: New testcase. Index: gcc/tree-ssa-phiprop.c =================================================================== *** gcc/tree-ssa-phiprop.c (revision 207757) --- gcc/tree-ssa-phiprop.c (working copy) *************** propagate_with_phi (basic_block bb, gimp *** 309,314 **** --- 309,320 ---- gimple def_stmt; tree vuse; + /* Only replace loads in blocks that post-dominate the PHI node. That + makes sure we don't end up speculating loads. */ + if (!dominated_by_p (CDI_POST_DOMINATORS, + bb, gimple_bb (use_stmt))) + continue; + /* Check whether this is a load of *ptr. */ if (!(is_gimple_assign (use_stmt) && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME *************** tree_ssa_phiprop (void) *** 380,385 **** --- 386,392 ---- size_t n; calculate_dominance_info (CDI_DOMINATORS); + calculate_dominance_info (CDI_POST_DOMINATORS); n = num_ssa_names; phivn = XCNEWVEC (struct phiprop_d, n); *************** tree_ssa_phiprop (void) *** 397,402 **** --- 404,411 ---- bbs.release (); free (phivn); + free_dominance_info (CDI_POST_DOMINATORS); + return 0; } Index: gcc/testsuite/gcc.dg/torture/pr60183.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr60183.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr60183.c (working copy) *************** *** 0 **** --- 1,38 ---- + /* { dg-do run } */ + + /* Large so an out-of-bound read will crash. */ + unsigned char c[0x30001] = { 1 }; + int j = 2; + + static void + foo (unsigned long *x, unsigned char *y) + { + int i; + unsigned long w = x[0]; + for (i = 0; i < j; i++) + { + w += *y; + y += 0x10000; + w += *y; + y += 0x10000; + } + x[1] = w; + } + + __attribute__ ((noinline, noclone)) void + bar (unsigned long *x) + { + foo (x, c); + } + + int + main () + { + unsigned long a[2] = { 0, -1UL }; + asm volatile (""::"r" (c):"memory"); + c[0] = 0; + bar (a); + if (a[1] != 0) + __builtin_abort (); + return 0; + }