Fix PR81889

Message ID alpine.LSU.2.20.1712111622320.12252@zhemvz.fhfr.qr
State New
Headers show
Series
  • Fix PR81889
Related show

Commit Message

Richard Biener Dec. 11, 2017, 3:25 p.m.
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  <rguenther@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.

Patch

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