This fixes PR61335 - symbolic range propagation in VRP is so weak
that we didn't notice this very old serious bug ... compare_values
can return "don't know" which is -2, but PHI node visiting handles
it the same as -1 (less than...).  Oops.

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

Richard.

2014-05-28  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/61335
        * tree-vrp.c (vrp_visit_phi_node): If the compare of old and
        new range fails, drop to varying.

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

Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c      (revision 210973)
--- gcc/tree-vrp.c      (working copy)
*************** vrp_visit_phi_node (gimple phi)
*** 8323,8330 ****
--- 8323,8336 ----
        && edges == old_edges
        && lhs_vr->type != VR_UNDEFINED)
      {
+       /* Compare old and new ranges, fall back to varying if the
+          values are not comparable.  */
        int cmp_min = compare_values (lhs_vr->min, vr_result.min);
+       if (cmp_min == -2)
+       goto varying;
        int cmp_max = compare_values (lhs_vr->max, vr_result.max);
+       if (cmp_max == -2)
+       goto varying;
  
        /* For non VR_RANGE or for pointers fall back to varying if
         the range changed.  */
Index: gcc/testsuite/gfortran.dg/pr61335.f90
===================================================================
*** gcc/testsuite/gfortran.dg/pr61335.f90       (revision 0)
--- gcc/testsuite/gfortran.dg/pr61335.f90       (working copy)
***************
*** 0 ****
--- 1,117 ----
+ ! { dg-do run }
+ ! { dg-additional-options "-fbounds-check" }
+ MODULE cp_units
+ 
+   INTEGER, PARAMETER :: default_string_length=80, dp=KIND(0.0D0)
+ 
+   LOGICAL, PRIVATE, PARAMETER          :: debug_this_module=.TRUE.
+   CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cp_units'
+   INTEGER, SAVE, PRIVATE               :: last_unit_id=0, last_unit_set_id=0
+ 
+   INTEGER, PARAMETER, PUBLIC :: cp_unit_max_kinds=8, 
cp_unit_basic_desc_length=15,&
+        cp_unit_desc_length=cp_unit_max_kinds*cp_unit_basic_desc_length, 
cp_ukind_max=9
+ 
+ CONTAINS
+ 
+   FUNCTION cp_to_string(i) RESULT(res)
+     INTEGER, INTENT(in)                      :: i
+     CHARACTER(len=6)                         :: res
+ 
+     INTEGER                                  :: iostat
+     REAL(KIND=dp)                            :: tmp_r
+ 
+     IF (i>999999 .OR. i<-99999) THEN
+        tmp_r=i
+        WRITE (res,fmt='(es6.1)',iostat=iostat) tmp_r
+     ELSE
+        WRITE (res,fmt='(i6)',iostat=iostat) i
+     END IF
+     IF (iostat/=0) THEN
+        STOP 7
+     END IF
+   END FUNCTION cp_to_string
+ 
+   SUBROUTINE cp_unit_create(string)
+     CHARACTER(len=*), INTENT(in)             :: string
+ 
+     CHARACTER(len=*), PARAMETER :: routineN = 'cp_unit_create', &
+       routineP = moduleN//':'//routineN
+ 
+     CHARACTER(default_string_length)         :: desc
+     CHARACTER(LEN=40)                        :: formatstr
+     INTEGER                                  :: i_high, i_low, i_unit, &
+                                                 len_string, next_power
+     INTEGER, DIMENSION(cp_unit_max_kinds)    :: kind_id, power, unit_id
+     LOGICAL                                  :: failure
+ 
+     failure=.FALSE.
+     unit_id=cp_units_none
+     kind_id=cp_ukind_none
+     power=0
+     i_low=1
+     i_high=1
+     len_string=LEN(string)
+     i_unit=0
+     next_power=1
+     DO WHILE(i_low<len_string)
+        IF (string(i_low:i_low)/=' ') EXIT
+        i_low=i_low+1
+     END DO
+     i_high=i_low
+     DO WHILE(i_high<=len_string)
+        IF ( string(i_high:i_high)==' '.OR.string(i_high:i_high)=='^'.OR.&
+             string(i_high:i_high)=='*'.OR.string(i_high:i_high)=='/') EXIT
+        i_high=i_high+1
+     END DO
+     DO WHILE(.NOT.failure)
+        IF (i_high<=i_low.OR.i_low>len_string) EXIT
+        i_unit=i_unit+1
+        IF (i_unit>cp_unit_max_kinds) THEN
+           EXIT
+        END IF
+        power(i_unit)=next_power
+        ! parse op
+        i_low=i_high
+        DO WHILE(i_low<=len_string)
+           IF (string(i_low:i_low)/=' ') EXIT
+           i_low=i_low+1
+        END DO
+        i_high=i_low
+        DO WHILE(i_high<=len_string)
+           IF ( string(i_high:i_high)==' '.OR.string(i_high:i_high)=='^'.OR.&
+                string(i_high:i_high)=='*'.OR.string(i_high:i_high)=='/') EXIT
+           i_high=i_high+1
+        END DO
+        IF (i_high<i_low.OR.i_low>len_string) EXIT
+ 
+        IF (i_high<=len_string) THEN
+           IF (string(i_low:i_high)=='^') THEN
+              i_low=i_high+1
+              DO WHILE(i_low<=len_string)
+                 IF (string(i_low:i_low)/=' ') EXIT
+                 i_low=i_low+1
+              END DO
+              i_high=i_low
+              DO WHILE(i_high<=len_string)
+                 SELECT CASE(string(i_high:i_high))
+                 CASE('+','-','0','1','2','3','4','5','6','7','8','9')
+                    i_high=i_high+1
+                 CASE default
+                    EXIT
+                 END SELECT
+              END DO
+              IF (i_high<=i_low.OR.i_low>len_string) THEN
+                 write(6,*) "BUG : XXX"//string//"XXX integer expected"
+                 STOP 1
+                 EXIT
+              END IF
+           END IF
+        ENDIF
+     END DO
+   END SUBROUTINE cp_unit_create
+ 
+ END MODULE cp_units
+ 
+ USE cp_units
+ CALL cp_unit_create("fs^-1")
+ END

Reply via email to