[PATCH] Fix PR55555

Richard Biener rguenther@suse.de
Mon Dec 17 12:54:00 GMT 2012


The following patch fixes a miscompilation due to bogus loop iteration
bound derived from array accesses in an inner loop.  idx_infer_loop_bounds
analyzes the evoultion of an SSA name with respect to a loop it is not
defined in - which seems to lead to random weird behavior.  The correct
thing to do (as documented) is to analyze the evolution with respect
to the loop the stmt we are interested in is in.

Bootstrap and regtest ongoing on x86_64-unknown-linux-gnu.

Thanks,
Richard.

2012-12-17  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/55555
	* tree-ssa-loop-niter.c (idx_infer_loop_bounds): Properly
	analyze evolution of the index for the loop it is used in.

	* gcc.dg/torture/pr55555.c: New testcase.

Index: gcc/tree-ssa-loop-niter.c
===================================================================
*** gcc/tree-ssa-loop-niter.c	(revision 194552)
--- gcc/tree-ssa-loop-niter.c	(working copy)
*************** idx_infer_loop_bounds (tree base, tree *
*** 2671,2677 ****
        upper = false;
      }
  
!   ev = instantiate_parameters (loop, analyze_scalar_evolution (loop, *idx));
    init = initial_condition (ev);
    step = evolution_part_in_loop_num (ev, loop->num);
  
--- 2671,2682 ----
        upper = false;
      }
  
!   struct loop *dloop = loop_containing_stmt (data->stmt);
!   if (!dloop)
!     return true;
! 
!   ev = analyze_scalar_evolution (dloop, *idx);
!   ev = instantiate_parameters (loop, ev);
    init = initial_condition (ev);
    step = evolution_part_in_loop_num (ev, loop->num);
  
Index: gcc/testsuite/gcc.dg/torture/pr55555.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr55555.c	(revision 0)
--- gcc/testsuite/gcc.dg/torture/pr55555.c	(working copy)
***************
*** 0 ****
--- 1,34 ----
+ /* { dg-do run } */
+ 
+ double s[4] = { 1.0, 2.0, 3.0, 4.0 }, pol_x[2] = { 5.0, 6.0 };
+ 
+ __attribute__((noinline)) int
+ foo (void)
+ {
+   double coef_x[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+   int lxp = 0;
+   if (lxp <= 1)
+     do
+       {
+ 	double t = pol_x[lxp];
+ 	long S;
+ 	long l = lxp * 4L - 1;
+ 	for (S = 1; S <= 4; S++)
+ 	  coef_x[S + l] = coef_x[S + l] + s[S - 1] * t;
+       }
+     while (lxp++ != 1);
+   asm volatile ("" : : "r" (coef_x) : "memory");
+   for (lxp = 0; lxp < 8; lxp++)
+     if (coef_x[lxp] != ((lxp & 3) + 1) * (5.0 + (lxp >= 4)))
+       __builtin_abort ();
+   return 1;
+ }
+ 
+ int
+ main ()
+ {
+   asm volatile ("" : : : "memory");
+   if (!foo ())
+     __builtin_abort ();
+   return 0;
+ }



More information about the Gcc-patches mailing list