Unrolling often has only rudimentary info for the upper bound of a loop
even though VRP would compute reasonable bounds for the variables
participating in the loop exit test.  This causes excessive peeling
and thus warnings from array bound and uninit warning code.

The following mitigates missing range-info somewhat because range-info
from early often persists on IV computation statements.  We already
use "ranges" on them but only their natural range.  The following
makes us use range info properly.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2017-12-11  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/81889
        * tree-ssa-loop-niter.c (infer_loop_bounds_from_signedness): Use
        range info from the non-wrapping IV instead of just the range
        of the type.

        * gfortran.dg/pr81889.f90: New testcase.

Index: gcc/tree-ssa-loop-niter.c
===================================================================
--- gcc/tree-ssa-loop-niter.c   (revision 255539)
+++ gcc/tree-ssa-loop-niter.c   (working copy)
@@ -3510,6 +3510,12 @@ infer_loop_bounds_from_signedness (struc
 
   low = lower_bound_in_type (type, type);
   high = upper_bound_in_type (type, type);
+  wide_int minv, maxv;
+  if (get_range_info (def, &minv, &maxv) == VR_RANGE)
+    {
+      low = wide_int_to_tree (type, minv);
+      high = wide_int_to_tree (type, maxv);
+    }
 
   record_nonwrapping_iv (loop, base, step, stmt, low, high, false, true);
 }
Index: gcc/testsuite/gfortran.dg/pr81889.f90
===================================================================
--- gcc/testsuite/gfortran.dg/pr81889.f90       (nonexistent)
+++ gcc/testsuite/gfortran.dg/pr81889.f90       (working copy)
@@ -0,0 +1,29 @@
+! { dg-do compile }
+! { dg-options "-O3 -Wall" }
+
+module m
+
+   type t
+      integer, dimension(:), pointer :: list
+   end type
+
+contains
+
+   subroutine s(n, p, Y)
+      integer, intent(in) :: n
+      type(t) :: p
+      real, dimension(:) :: Y
+
+      real, dimension(1:16) :: xx
+
+      if (n > 3) then
+         xx(1:n) = 0.
+         print *, xx(1:n)
+      else
+         xx(1:n) = Y(p%list(1:n)) ! { dg-bogus "uninitialized" }
+         print *, sum(xx(1:n))
+      end if
+
+   end subroutine
+
+end module

Reply via email to