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;
+ }

Reply via email to