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