This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR68963
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Jan Hubicka <hubicka at ucw dot cz>
- Date: Mon, 22 Feb 2016 13:50:01 +0100 (CET)
- Subject: [PATCH] Fix PR68963
- Authentication-results: sourceware.org; auth=none
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;
+ }