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