This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR68963


The following patch fixes invalid upper bounds recorded for conditonal
array accesses - it doesn't depend on whether their IV wrap or not
(and we were unsetting 'reliable' only anyway).  In fact conditional
accesses should be good enough for an estimate, just wrapping ones
not.  Until we determine whether the controlling expression is
dependent on the loop IV that's probably the best to do here.

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

Honza, about reliable vs. non-reliable - was that the original intent
or did you want to always record 'reliable' but really reset 'upper'
here?

Thanks,
Richard.

2016-02-22  Richard Biener  <rguenther@suse.de>

	PR middle-end/68963
	* tree-ssa-loop-niter.c (idx_infer_loop_bounds): Do not record an
	upper bound for accesses not always executed.  Do not record an
	estimate for accesses with wrapping IVs.

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

Index: gcc/tree-ssa-loop-niter.c
===================================================================
*** gcc/tree-ssa-loop-niter.c	(revision 233598)
--- gcc/tree-ssa-loop-niter.c	(working copy)
*************** idx_infer_loop_bounds (tree base, tree *
*** 3183,3196 ****
        && tree_int_cst_compare (next, high) <= 0)
      return true;
  
!   /* If access is not executed on every iteration, we must ensure that overlow may
!      not make the access valid later.  */
!   if (!dominated_by_p (CDI_DOMINATORS, loop->latch, gimple_bb (data->stmt))
!       && scev_probably_wraps_p (initial_condition_in_loop_num (ev, loop->num),
! 				step, data->stmt, loop, true))
      reliable = false;
  
!   record_nonwrapping_iv (loop, init, step, data->stmt, low, high, reliable, upper);
    return true;
  }
  
--- 3183,3200 ----
        && tree_int_cst_compare (next, high) <= 0)
      return true;
  
!   /* If access is not executed on every iteration we cannot derive any
!      upper bound.  */
!   if (!dominated_by_p (CDI_DOMINATORS, loop->latch, gimple_bb (data->stmt)))
!     upper = false;
!   /* If the IV of the access may wrap then the array size is not good for
!      an estimate either.  */
!   if (scev_probably_wraps_p (initial_condition_in_loop_num (ev, loop->num),
! 			     step, data->stmt, loop, true))
      reliable = false;
  
!   record_nonwrapping_iv (loop, init, step, data->stmt, low, high,
! 			 reliable, upper);
    return true;
  }
  
Index: gcc/testsuite/gcc.dg/torture/pr68963.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr68963.c	(revision 0)
--- gcc/testsuite/gcc.dg/torture/pr68963.c	(working copy)
***************
*** 0 ****
--- 1,41 ----
+ /* { dg-do run } */
+ 
+ static const float a[3] = { 1, 2, 3 };
+ int b = 3;
+ 
+ __attribute__((noinline, noclone)) void
+ bar (int x)
+ {
+   if (x != b++)
+     __builtin_abort ();
+ }
+ 
+ void
+ foo (float *x, int y)
+ {
+   int i;
+   for (i = 0; i < 2 * y; ++i)
+     {
+       if (i < y)
+ 	x[i] = a[i];
+       else
+ 	{
+ 	  bar (i);
+ 	  x[i] = a[i - y];
+ 	}
+     }
+ }
+ 
+ int
+ main ()
+ {
+   float x[10];
+   unsigned int i;
+   for (i = 0; i < 10; ++i)
+     x[i] = 1337;
+   foo (x, 3);
+   for (i = 0; i < 10; ++i)
+     if (x[i] != (i < 6 ? (i % 3) + 1 : 1337))
+       __builtin_abort ();
+   return 0;
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]