@@ -1397,6 +1397,20 @@ predicate nonNanGuardedVariable(Expr guard, VariableAccess v, boolean branch) {
13971397  nanExcludingComparison ( guard ,  branch ) 
13981398} 
13991399
1400+ /** 
1401+  * Adjusts a lower bound to its meaning for integral types. 
1402+  * 
1403+  * Examples: 
1404+  * `>= 3.0` becomes `3.0` 
1405+  * ` > 3.0` becomes `4.0` 
1406+  * `>= 3.5` becomes `4.0` 
1407+  * ` > 3.5` becomes `4.0` 
1408+  */ 
1409+ bindingset [ strictness,  lb] 
1410+ private  float  adjustLowerBoundIntegral ( RelationStrictness  strictness ,  float  lb )  { 
1411+   if  strictness  =  Nonstrict ( )  and  lb .floor ( )  =  lb  then  result  =  lb  else  result  =  safeFloor ( lb )  +  1 
1412+ } 
1413+ 
14001414/** 
14011415 * If the guard is a comparison of the form `p*v + q <CMP> r`, then this 
14021416 * predicate uses the bounds information for `r` to compute a lower bound 
@@ -1408,15 +1422,27 @@ private predicate lowerBoundFromGuard(Expr guard, VariableAccess v, float lb, bo
14081422  | 
14091423    if  nonNanGuardedVariable ( guard ,  v ,  branch ) 
14101424    then 
1411-       if 
1412-         strictness  =  Nonstrict ( )  or 
1413-         not  getVariableRangeType ( v .getTarget ( ) )  instanceof  IntegralType 
1414-       then  lb  =  childLB 
1415-       else  lb  =  childLB  +  1 
1425+       if  getVariableRangeType ( v .getTarget ( ) )  instanceof  IntegralType 
1426+       then  lb  =  adjustLowerBoundIntegral ( strictness ,  childLB ) 
1427+       else  lb  =  childLB 
14161428    else  lb  =  varMinVal ( v .getTarget ( ) ) 
14171429  ) 
14181430} 
14191431
1432+ /** 
1433+  * Adjusts an upper bound to its meaning for integral types. 
1434+  * 
1435+  * Examples: 
1436+  * `<= 3.0` becomes `3.0` 
1437+  * ` < 3.0` becomes `2.0` 
1438+  * `<= 3.5` becomes `3.0` 
1439+  * ` < 3.5` becomes `3.0` 
1440+  */ 
1441+ bindingset [ strictness,  ub] 
1442+ private  float  adjustUpperBoundIntegral ( RelationStrictness  strictness ,  float  ub )  { 
1443+   if  strictness  =  Strict ( )  and  ub .floor ( )  =  ub  then  result  =  ub  -  1  else  result  =  safeFloor ( ub ) 
1444+ } 
1445+ 
14201446/** 
14211447 * If the guard is a comparison of the form `p*v + q <CMP> r`, then this 
14221448 * predicate uses the bounds information for `r` to compute a upper bound 
@@ -1428,11 +1454,9 @@ private predicate upperBoundFromGuard(Expr guard, VariableAccess v, float ub, bo
14281454  | 
14291455    if  nonNanGuardedVariable ( guard ,  v ,  branch ) 
14301456    then 
1431-       if 
1432-         strictness  =  Nonstrict ( )  or 
1433-         not  getVariableRangeType ( v .getTarget ( ) )  instanceof  IntegralType 
1434-       then  ub  =  childUB 
1435-       else  ub  =  childUB  -  1 
1457+       if  getVariableRangeType ( v .getTarget ( ) )  instanceof  IntegralType 
1458+       then  ub  =  adjustUpperBoundIntegral ( strictness ,  childUB ) 
1459+       else  ub  =  childUB 
14361460    else  ub  =  varMaxVal ( v .getTarget ( ) ) 
14371461  ) 
14381462} 
@@ -1472,7 +1496,7 @@ private predicate boundFromGuard(
14721496 * lower or upper bound for `v`. 
14731497 */ 
14741498private  predicate  linearBoundFromGuard ( 
1475-   ComparisonOperation  guard ,  VariableAccess  v ,  float  p ,  float  q ,  float  boundValue , 
1499+   ComparisonOperation  guard ,  VariableAccess  v ,  float  p ,  float  q ,  float  r , 
14761500  boolean  isLowerBound ,  // Is this a lower or an upper bound? 
14771501  RelationStrictness  strictness ,  boolean  branch  // Which control-flow branch is this bound valid on? 
14781502)  { 
@@ -1487,11 +1511,11 @@ private predicate linearBoundFromGuard(
14871511  | 
14881512    isLowerBound  =  directionIsGreater ( dir )  and 
14891513    strictness  =  st  and 
1490-     getBounds ( rhs ,  boundValue ,  isLowerBound ) 
1514+     getBounds ( rhs ,  r ,  isLowerBound ) 
14911515    or 
14921516    isLowerBound  =  directionIsLesser ( dir )  and 
14931517    strictness  =  Nonstrict ( )  and 
1494-     exprTypeBounds ( rhs ,  boundValue ,  isLowerBound ) 
1518+     exprTypeBounds ( rhs ,  r ,  isLowerBound ) 
14951519  ) 
14961520  or 
14971521  // For x == RHS, we create the following bounds: 
@@ -1502,7 +1526,7 @@ private predicate linearBoundFromGuard(
15021526  exists ( Expr  lhs ,  Expr  rhs  | 
15031527    linearAccess ( lhs ,  v ,  p ,  q )  and 
15041528    eqOpWithSwapAndNegate ( guard ,  lhs ,  rhs ,  true ,  branch )  and 
1505-     getBounds ( rhs ,  boundValue ,  isLowerBound )  and 
1529+     getBounds ( rhs ,  r ,  isLowerBound )  and 
15061530    strictness  =  Nonstrict ( ) 
15071531  ) 
15081532  // x != RHS and !x are handled elsewhere 
0 commit comments