The following fixes PR76490 which happens because how VRP expects
+INF vs. +INF(OVF) to behave wrt comparisons.  I fixed all
operand_equal_p cases that matter.

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

Richard.

2016-08-15  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/76490
        * tree-vrp.c (value_range_constant_singleton): Use vrp_operand_equal_p
        to handle overflow max/min correctly.
        (vrp_valueize): Likewise.
        (union_ranges): Likewise.
        (intersect_ranges): Likewise.

        * gfortran.fortran-torture/compile/pr76490.f90: New testcase.

Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c      (revision 239460)
--- gcc/tree-vrp.c      (working copy)
*************** static tree
*** 1422,1428 ****
  value_range_constant_singleton (value_range *vr)
  {
    if (vr->type == VR_RANGE
!       && operand_equal_p (vr->min, vr->max, 0)
        && is_gimple_min_invariant (vr->min))
      return vr->min;
  
--- 1423,1429 ----
  value_range_constant_singleton (value_range *vr)
  {
    if (vr->type == VR_RANGE
!       && vrp_operand_equal_p (vr->min, vr->max)
        && is_gimple_min_invariant (vr->min))
      return vr->min;
  
*************** vrp_valueize (tree name)
*** 7028,7035 ****
      {
        value_range *vr = get_value_range (name);
        if (vr->type == VR_RANGE
!         && (vr->min == vr->max
!             || operand_equal_p (vr->min, vr->max, 0)))
        return vr->min;
      }
    return name;
--- 7006,7012 ----
      {
        value_range *vr = get_value_range (name);
        if (vr->type == VR_RANGE
!         && vrp_operand_equal_p (vr->min, vr->max))
        return vr->min;
      }
    return name;
*************** union_ranges (enum value_range_type *vr0
*** 7995,8002 ****
              enum value_range_type vr1type,
              tree vr1min, tree vr1max)
  {
!   bool mineq = operand_equal_p (*vr0min, vr1min, 0);
!   bool maxeq = operand_equal_p (*vr0max, vr1max, 0);
  
    /* [] is vr0, () is vr1 in the following classification comments.  */
    if (mineq && maxeq)
--- 7972,7979 ----
              enum value_range_type vr1type,
              tree vr1min, tree vr1max)
  {
!   bool mineq = vrp_operand_equal_p (*vr0min, vr1min);
!   bool maxeq = vrp_operand_equal_p (*vr0max, vr1max);
  
    /* [] is vr0, () is vr1 in the following classification comments.  */
    if (mineq && maxeq)
*************** intersect_ranges (enum value_range_type
*** 8266,8273 ****
                  enum value_range_type vr1type,
                  tree vr1min, tree vr1max)
  {
!   bool mineq = operand_equal_p (*vr0min, vr1min, 0);
!   bool maxeq = operand_equal_p (*vr0max, vr1max, 0);
  
    /* [] is vr0, () is vr1 in the following classification comments.  */
    if (mineq && maxeq)
--- 8243,8250 ----
                  enum value_range_type vr1type,
                  tree vr1min, tree vr1max)
  {
!   bool mineq = vrp_operand_equal_p (*vr0min, vr1min);
!   bool maxeq = vrp_operand_equal_p (*vr0max, vr1max);
  
    /* [] is vr0, () is vr1 in the following classification comments.  */
    if (mineq && maxeq)
Index: gcc/testsuite/gfortran.fortran-torture/compile/pr76490.f90
===================================================================
*** gcc/testsuite/gfortran.fortran-torture/compile/pr76490.f90  (revision 0)
--- gcc/testsuite/gfortran.fortran-torture/compile/pr76490.f90  (working copy)
***************
*** 0 ****
--- 1,23 ----
+ program membug
+ call bug1()
+ end program membug
+ subroutine unknown(x1,y1,ibig)
+    write(*,*)x1,y1,ibig
+ end subroutine unknown
+ subroutine bug1()
+ real arrayq(3000)            
+    isize=0
+    ibig=-1
+    x2=0
+ 10 continue                               
+    isize=isize+1
+    arrayq(isize)=x2                
+ 15 continue
+    call unknown(x1,y1,ibig)
+    if(ibig.eq.1)then
+       goto 10
+    elseif(ibig.eq.2)then       
+       isize=max(1,isize-1)
+       goto 15
+    endif
+ end subroutine bug1

Reply via email to