@@ -197,6 +197,7 @@ class CondReason extends Reason, TCondReason {
197197 * Holds if a cast from `fromtyp` to `totyp` can be ignored for the purpose of
198198 * range analysis.
199199 */
200+ pragma [ inline]
200201private predicate safeCast ( IntegralType fromtyp , IntegralType totyp ) {
201202 fromtyp .getSize ( ) < totyp .getSize ( ) and
202203 (
@@ -256,7 +257,7 @@ private class NarrowingCastInstruction extends ConvertInstruction {
256257 * - `upper = true` : `i <= op + delta`
257258 * - `upper = false` : `i >= op + delta`
258259 */
259- private predicate boundFlowStep ( Instruction i , Operand op , int delta , boolean upper ) {
260+ private predicate boundFlowStep ( Instruction i , NonPhiOperand op , int delta , boolean upper ) {
260261 valueFlowStep ( i , op , delta ) and
261262 ( upper = true or upper = false )
262263 or
@@ -425,12 +426,27 @@ private predicate boundedPhiOperand(
425426 )
426427}
427428
429+ /** Holds if `v != e + delta` at `pos`. */
430+ private predicate unequalFlowStep (
431+ Operand op1 , Operand op2 , int delta , Reason reason
432+ ) {
433+ exists ( IRGuardCondition guard , boolean testIsTrue |
434+ guard = eqFlowCond ( valueNumberOfOperand ( op1 ) , op2 , delta , false , testIsTrue ) and
435+ guard .controls ( op1 .getInstruction ( ) .getBlock ( ) , testIsTrue ) and
436+ reason = TCondReason ( guard )
437+ )
438+ }
439+
428440/**
429441 * Holds if `op != b + delta` at `pos`.
430442 */
431443private predicate unequalOperand ( Operand op , Bound b , int delta , Reason reason ) {
432- // TODO: implement this
433- none ( )
444+ exists ( Operand op2 , int d1 , int d2 |
445+ unequalFlowStep ( op , op2 , delta , reason ) and
446+ boundedNonPhiOperand ( op2 , b , d2 , true , _, _, _) and
447+ boundedNonPhiOperand ( op2 , b , d2 , true , _, _, _) and
448+ delta = d1 + d2
449+ )
434450}
435451
436452private predicate boundedPhiCandValidForEdge (
@@ -544,50 +560,47 @@ private predicate boundedCastExpr(
544560private predicate boundedInstruction (
545561 Instruction i , Bound b , int delta , boolean upper , boolean fromBackEdge , int origdelta , Reason reason
546562) {
547- i instanceof PhiInstruction and
548- forex ( PhiOperand op | op = i .getAnOperand ( ) |
549- boundedPhiCandValidForEdge ( i , b , delta , upper , fromBackEdge , origdelta , reason , op )
550- )
551- or
552- i = b .getInstruction ( delta ) and
553- ( upper = true or upper = false ) and
554- fromBackEdge = false and
555- origdelta = delta and
556- reason = TNoReason ( )
557- or
558- exists ( Operand mid , int d1 , int d2 |
559- boundFlowStep ( i , mid , d1 , upper ) and
560- boundedNonPhiOperand ( mid , b , d2 , upper , fromBackEdge , origdelta , reason ) and
561- delta = d1 + d2 and
562- not exists ( getValue ( getConstantValue ( i ) ) )
563- )
564- or
565- exists ( Operand mid , int factor , int d |
566- boundFlowStepMul ( i , mid , factor ) and
567- boundedNonPhiOperand ( mid , b , d , upper , fromBackEdge , origdelta , reason ) and
568- b instanceof ZeroBound and
569- delta = d * factor and
570- not exists ( getValue ( getConstantValue ( i ) ) )
571- )
572- or
573- exists ( Operand mid , int factor , int d |
574- boundFlowStepDiv ( i , mid , factor ) and
575- boundedNonPhiOperand ( mid , b , d , upper , fromBackEdge , origdelta , reason ) and
576- d >= 0 and
577- b instanceof ZeroBound and
578- delta = d / factor and
579- not exists ( getValue ( getConstantValue ( i ) ) )
580- )
581- or
582- exists ( NarrowingCastInstruction cast |
583- cast = i and
584- safeNarrowingCast ( cast , upper .booleanNot ( ) ) and
585- boundedCastExpr ( cast , b , delta , upper , fromBackEdge , origdelta , reason )
563+ isReducibleCFG ( i .getFunction ( ) ) and
564+ (
565+ i instanceof PhiInstruction and
566+ forex ( PhiOperand op | op = i .getAnOperand ( ) |
567+ boundedPhiCandValidForEdge ( i , b , delta , upper , fromBackEdge , origdelta , reason , op )
568+ )
569+ or
570+ i = b .getInstruction ( delta ) and
571+ ( upper = true or upper = false ) and
572+ fromBackEdge = false and
573+ origdelta = delta and
574+ reason = TNoReason ( )
575+ or
576+ exists ( Operand mid , int d1 , int d2 |
577+ boundFlowStep ( i , mid , d1 , upper ) and
578+ boundedNonPhiOperand ( mid , b , d2 , upper , fromBackEdge , origdelta , reason ) and
579+ delta = d1 + d2 and
580+ not exists ( getValue ( getConstantValue ( i ) ) )
581+ )
582+ or
583+ exists ( Operand mid , int factor , int d |
584+ boundFlowStepMul ( i , mid , factor ) and
585+ boundedNonPhiOperand ( mid , b , d , upper , fromBackEdge , origdelta , reason ) and
586+ b instanceof ZeroBound and
587+ delta = d * factor and
588+ not exists ( getValue ( getConstantValue ( i ) ) )
589+ )
590+ or
591+ exists ( Operand mid , int factor , int d |
592+ boundFlowStepDiv ( i , mid , factor ) and
593+ boundedNonPhiOperand ( mid , b , d , upper , fromBackEdge , origdelta , reason ) and
594+ d >= 0 and
595+ b instanceof ZeroBound and
596+ delta = d / factor and
597+ not exists ( getValue ( getConstantValue ( i ) ) )
598+ )
599+ or
600+ exists ( NarrowingCastInstruction cast |
601+ cast = i and
602+ safeNarrowingCast ( cast , upper .booleanNot ( ) ) and
603+ boundedCastExpr ( cast , b , delta , upper , fromBackEdge , origdelta , reason )
604+ )
586605 )
587606}
588-
589- predicate backEdge ( PhiInstruction phi , PhiOperand op ) {
590- phi .getAnOperand ( ) = op and
591- phi .getBlock ( ) .dominates ( op .getPredecessorBlock ( ) )
592- // TODO: identify backedges during IR construction
593- }
0 commit comments