@@ -427,11 +427,11 @@ private predicate exprDependsOnDef(Expr e, RangeSsaDefinition srcDef, StackVaria
427427private predicate phiDependsOnDef (
428428 RangeSsaDefinition phi , StackVariable v , RangeSsaDefinition srcDef , StackVariable srcVar
429429) {
430- exists ( VariableAccess access , ComparisonOperation guard |
430+ exists ( VariableAccess access , Expr guard |
431431 access = v .getAnAccess ( ) and
432432 phi .isGuardPhi ( access , guard , _)
433433 |
434- exprDependsOnDef ( guard .getAnOperand ( ) , srcDef , srcVar ) or
434+ exprDependsOnDef ( guard .( ComparisonOperation ) . getAnOperand ( ) , srcDef , srcVar ) or
435435 exprDependsOnDef ( access , srcDef , srcVar )
436436 )
437437 or
@@ -1132,9 +1132,7 @@ private float boolConversionUpperBound(Expr expr) {
11321132 * use the guard to deduce that the lower bound is 2 inside the block.
11331133 */
11341134private float getPhiLowerBounds ( StackVariable v , RangeSsaDefinition phi ) {
1135- exists (
1136- VariableAccess access , ComparisonOperation guard , boolean branch , float defLB , float guardLB
1137- |
1135+ exists ( VariableAccess access , Expr guard , boolean branch , float defLB , float guardLB |
11381136 access = v .getAnAccess ( ) and
11391137 phi .isGuardPhi ( access , guard , branch ) and
11401138 lowerBoundFromGuard ( guard , access , guardLB , branch ) and
@@ -1146,23 +1144,21 @@ private float getPhiLowerBounds(StackVariable v, RangeSsaDefinition phi) {
11461144 or
11471145 exists ( VariableAccess access , float neConstant , float lower |
11481146 isNEPhi ( v , phi , access , neConstant ) and
1149- lower = getFullyConvertedLowerBounds ( access ) and
1147+ lower = getTruncatedLowerBounds ( access ) and
11501148 if lower = neConstant then result = lower + 1 else result = lower
11511149 )
11521150 or
11531151 exists ( VariableAccess access |
11541152 isUnsupportedGuardPhi ( v , phi , access ) and
1155- result = getFullyConvertedLowerBounds ( access )
1153+ result = getTruncatedLowerBounds ( access )
11561154 )
11571155 or
11581156 result = getDefLowerBounds ( phi .getAPhiInput ( v ) , v )
11591157}
11601158
11611159/** See comment for `getPhiLowerBounds`, above. */
11621160private float getPhiUpperBounds ( StackVariable v , RangeSsaDefinition phi ) {
1163- exists (
1164- VariableAccess access , ComparisonOperation guard , boolean branch , float defUB , float guardUB
1165- |
1161+ exists ( VariableAccess access , Expr guard , boolean branch , float defUB , float guardUB |
11661162 access = v .getAnAccess ( ) and
11671163 phi .isGuardPhi ( access , guard , branch ) and
11681164 upperBoundFromGuard ( guard , access , guardUB , branch ) and
@@ -1174,13 +1170,13 @@ private float getPhiUpperBounds(StackVariable v, RangeSsaDefinition phi) {
11741170 or
11751171 exists ( VariableAccess access , float neConstant , float upper |
11761172 isNEPhi ( v , phi , access , neConstant ) and
1177- upper = getFullyConvertedUpperBounds ( access ) and
1173+ upper = getTruncatedUpperBounds ( access ) and
11781174 if upper = neConstant then result = upper - 1 else result = upper
11791175 )
11801176 or
11811177 exists ( VariableAccess access |
11821178 isUnsupportedGuardPhi ( v , phi , access ) and
1183- result = getFullyConvertedUpperBounds ( access )
1179+ result = getTruncatedUpperBounds ( access )
11841180 )
11851181 or
11861182 result = getDefUpperBounds ( phi .getAPhiInput ( v ) , v )
@@ -1334,7 +1330,7 @@ private predicate unanalyzableDefBounds(RangeSsaDefinition def, StackVariable v,
13341330 * inferences about `v`.
13351331 */
13361332bindingset [ guard, v, branch]
1337- predicate nonNanGuardedVariable ( ComparisonOperation guard , VariableAccess v , boolean branch ) {
1333+ predicate nonNanGuardedVariable ( Expr guard , VariableAccess v , boolean branch ) {
13381334 getVariableRangeType ( v .getTarget ( ) ) instanceof IntegralType
13391335 or
13401336 getVariableRangeType ( v .getTarget ( ) ) instanceof FloatingPointType and
@@ -1353,9 +1349,7 @@ predicate nonNanGuardedVariable(ComparisonOperation guard, VariableAccess v, boo
13531349 * predicate uses the bounds information for `r` to compute a lower bound
13541350 * for `v`.
13551351 */
1356- private predicate lowerBoundFromGuard (
1357- ComparisonOperation guard , VariableAccess v , float lb , boolean branch
1358- ) {
1352+ private predicate lowerBoundFromGuard ( Expr guard , VariableAccess v , float lb , boolean branch ) {
13591353 exists ( float childLB , RelationStrictness strictness |
13601354 boundFromGuard ( guard , v , childLB , true , strictness , branch )
13611355 |
@@ -1375,9 +1369,7 @@ private predicate lowerBoundFromGuard(
13751369 * predicate uses the bounds information for `r` to compute a upper bound
13761370 * for `v`.
13771371 */
1378- private predicate upperBoundFromGuard (
1379- ComparisonOperation guard , VariableAccess v , float ub , boolean branch
1380- ) {
1372+ private predicate upperBoundFromGuard ( Expr guard , VariableAccess v , float ub , boolean branch ) {
13811373 exists ( float childUB , RelationStrictness strictness |
13821374 boundFromGuard ( guard , v , childUB , false , strictness , branch )
13831375 |
@@ -1397,7 +1389,7 @@ private predicate upperBoundFromGuard(
13971389 * `linearBoundFromGuard`.
13981390 */
13991391private predicate boundFromGuard (
1400- ComparisonOperation guard , VariableAccess v , float boundValue , boolean isLowerBound ,
1392+ Expr guard , VariableAccess v , float boundValue , boolean isLowerBound ,
14011393 RelationStrictness strictness , boolean branch
14021394) {
14031395 exists ( float p , float q , float r , boolean isLB |
@@ -1410,6 +1402,15 @@ private predicate boundFromGuard(
14101402 or
14111403 p < 0 and isLowerBound = isLB .booleanNot ( )
14121404 )
1405+ or
1406+ // When `!e` is true, we know that `0 <= e <= 0`
1407+ exists ( float p , float q , Expr e |
1408+ linearAccess ( e , v , p , q ) and
1409+ eqZeroWithNegate ( guard , e , true , branch ) and
1410+ boundValue = ( 0.0 - q ) / p and
1411+ isLowerBound = [ false , true ] and
1412+ strictness = Nonstrict ( )
1413+ )
14131414}
14141415
14151416/**
@@ -1487,6 +1488,15 @@ private predicate isNEPhi(
14871488 linearAccess ( linearExpr , access , p , q ) and
14881489 neConstant = ( r - q ) / p
14891490 )
1491+ or
1492+ exists ( Expr op , boolean branch , Expr linearExpr , float p , float q |
1493+ access .getTarget ( ) = v and
1494+ phi .isGuardPhi ( access , op , branch ) and
1495+ eqZeroWithNegate ( op , linearExpr , false , branch ) and
1496+ v .getUnspecifiedType ( ) instanceof IntegralOrEnumType and // Float `!` is too imprecise
1497+ linearAccess ( linearExpr , access , p , q ) and
1498+ neConstant = ( 0.0 - q ) / p
1499+ )
14901500}
14911501
14921502/**
@@ -1496,10 +1506,13 @@ private predicate isNEPhi(
14961506 * compile-time constant.
14971507 */
14981508private predicate isUnsupportedGuardPhi ( Variable v , RangeSsaDefinition phi , VariableAccess access ) {
1499- exists ( ComparisonOperation cmp , boolean branch |
1509+ exists ( Expr cmp , boolean branch |
1510+ eqOpWithSwapAndNegate ( cmp , _, _, false , branch )
1511+ or
1512+ eqZeroWithNegate ( cmp , _, false , branch )
1513+ |
15001514 access .getTarget ( ) = v and
15011515 phi .isGuardPhi ( access , cmp , branch ) and
1502- eqOpWithSwapAndNegate ( cmp , _, _, false , branch ) and
15031516 not isNEPhi ( v , phi , access , _)
15041517 )
15051518}
0 commit comments