@@ -588,7 +588,7 @@ class IRGuardCondition extends Instruction {
588588 /** Holds if (determined by this guard) `op == k` evaluates to `areEqual` if this expression evaluates to `value`. */
589589 pragma [ inline]
590590 predicate comparesEq ( Operand op , int k , boolean areEqual , AbstractValue value ) {
591- unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , false , value )
591+ unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , value )
592592 }
593593
594594 /**
@@ -610,7 +610,7 @@ class IRGuardCondition extends Instruction {
610610 pragma [ inline]
611611 predicate ensuresEq ( Operand op , int k , IRBlock block , boolean areEqual ) {
612612 exists ( AbstractValue value |
613- unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , false , value ) and
613+ unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , value ) and
614614 this .valueControls ( block , value )
615615 )
616616 }
@@ -636,7 +636,7 @@ class IRGuardCondition extends Instruction {
636636 pragma [ inline]
637637 predicate ensuresEqEdge ( Operand op , int k , IRBlock pred , IRBlock succ , boolean areEqual ) {
638638 exists ( AbstractValue value |
639- unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , false , value ) and
639+ unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , value ) and
640640 this .valueControlsEdge ( pred , succ , value )
641641 )
642642 }
@@ -849,75 +849,35 @@ private module Cached {
849849
850850 /**
851851 * Holds if `op == k` is `areEqual` given that `test` is equal to `value`.
852- *
853- * Many internal predicates in this file have a `inNonZeroCase` column.
854- * Ideally, the `k` column would be a type such as `Option<int>::Option`, to
855- * represent whether we have a concrete value `k` such that `op == k`, or whether
856- * we only know that `op != 0`.
857- * However, cannot instantiate `Option` with an infinite type. Thus the boolean
858- * `inNonZeroCase` is used to distinquish the `Some` (where we have a concrete
859- * value `k`) and `None` cases (where we only know that `op != 0`).
860- *
861- * Thus, if `inNonZeroCase = true` then `op != 0` and the value of `k` is
862- * meaningless.
863- *
864- * To see why `inNonZeroCase` is needed consider the following C program:
865- * ```c
866- * char* p = ...;
867- * if(p) {
868- * use(p);
869- * }
870- * ```
871- * in C++ there would be an int-to-bool conversion on `p`. However, since C
872- * does not have booleans there is no conversion. We want to be able to
873- * conclude that `p` is non-zero in the true branch, so we need to give `k`
874- * some value. However, simply setting `k = 1` would make the rest of the
875- * analysis think that `k == 1` holds inside the branch. So we distinquish
876- * between the above case and
877- * ```c
878- * if(p == 1) {
879- * use(p)
880- * }
881- * ```
882- * by setting `inNonZeroCase` to `true` in the former case, but not in the
883- * latter.
884852 */
885853 cached
886854 predicate unary_compares_eq (
887- ValueNumber test , Operand op , int k , boolean areEqual , boolean inNonZeroCase ,
888- AbstractValue value
855+ ValueNumber test , Operand op , int k , boolean areEqual , AbstractValue value
889856 ) {
890857 /* The simple case where the test *is* the comparison so areEqual = testIsTrue xor eq. */
891- exists ( AbstractValue v | unary_simple_comparison_eq ( test , op , k , inNonZeroCase , v ) |
858+ exists ( AbstractValue v | unary_simple_comparison_eq ( test , op , k , v ) |
892859 areEqual = true and value = v
893860 or
894861 areEqual = false and value = v .getDualValue ( )
895862 )
896863 or
897- unary_complex_eq ( test , op , k , areEqual , inNonZeroCase , value )
864+ unary_complex_eq ( test , op , k , areEqual , value )
898865 or
899866 /* (x is true => (op == k)) => (!x is false => (op == k)) */
900- exists ( AbstractValue dual , boolean inNonZeroCase0 |
867+ exists ( AbstractValue dual |
901868 value = dual .getDualValue ( ) and
902- unary_compares_eq ( test .( LogicalNotValueNumber ) .getUnary ( ) , op , k , inNonZeroCase0 , areEqual ,
903- dual )
904- |
905- k = 0 and inNonZeroCase = inNonZeroCase0
906- or
907- k != 0 and inNonZeroCase = true
869+ unary_compares_eq ( test .( LogicalNotValueNumber ) .getUnary ( ) , op , k , areEqual , dual )
908870 )
909871 or
910872 // ((test is `areEqual` => op == const + k2) and const == `k1`) =>
911873 // test is `areEqual` => op == k1 + k2
912- inNonZeroCase = false and
913874 exists ( int k1 , int k2 , Instruction const |
914875 compares_eq ( test , op , const .getAUse ( ) , k2 , areEqual , value ) and
915876 int_value ( const ) = k1 and
916877 k = k1 + k2
917878 )
918879 or
919- unary_compares_eq ( test .( BuiltinExpectCallValueNumber ) .getCondition ( ) , op , k , areEqual ,
920- inNonZeroCase , value )
880+ unary_compares_eq ( test .( BuiltinExpectCallValueNumber ) .getCondition ( ) , op , k , areEqual , value )
921881 }
922882
923883 /** Rearrange various simple comparisons into `left == right + k` form. */
@@ -986,27 +946,24 @@ private module Cached {
986946
987947 /** Rearrange various simple comparisons into `op == k` form. */
988948 private predicate unary_simple_comparison_eq (
989- ValueNumber test , Operand op , int k , boolean inNonZeroCase , AbstractValue value
949+ ValueNumber test , Operand op , int k , AbstractValue value
990950 ) {
991951 exists ( CaseEdge case , SwitchConditionValueNumber condition |
992952 condition = test and
993953 op = condition .getExpressionOperand ( ) and
994954 case = value .( MatchValue ) .getCase ( ) and
995955 exists ( condition .getSuccessor ( case ) ) and
996- case .getValue ( ) .toInt ( ) = k and
997- inNonZeroCase = false
956+ case .getValue ( ) .toInt ( ) = k
998957 )
999958 or
1000959 isRelevantUnaryComparisonOperand ( op ) and
1001960 op .getDef ( ) = test .getAnInstruction ( ) and
1002961 (
1003962 k = 1 and
1004- value .( BooleanValue ) .getValue ( ) = true and
1005- inNonZeroCase = true
963+ value .( BooleanValue ) .getValue ( ) = true
1006964 or
1007965 k = 0 and
1008- value .( BooleanValue ) .getValue ( ) = false and
1009- inNonZeroCase = false
966+ value .( BooleanValue ) .getValue ( ) = false
1010967 )
1011968 }
1012969
@@ -1061,13 +1018,12 @@ private module Cached {
10611018 * an instruction that compares the value of `__builtin_expect(op == k, _)` to `0`.
10621019 */
10631020 private predicate unary_builtin_expect_eq (
1064- CompareValueNumber cmp , Operand op , int k , boolean areEqual , boolean inNonZeroCase ,
1065- AbstractValue value
1021+ CompareValueNumber cmp , Operand op , int k , boolean areEqual , AbstractValue value
10661022 ) {
10671023 exists ( BuiltinExpectCallValueNumber call , Instruction const , AbstractValue innerValue |
10681024 int_value ( const ) = 0 and
10691025 cmp .hasOperands ( call .getAUse ( ) , const .getAUse ( ) ) and
1070- unary_compares_eq ( call .getCondition ( ) , op , k , areEqual , inNonZeroCase , innerValue )
1026+ unary_compares_eq ( call .getCondition ( ) , op , k , areEqual , innerValue )
10711027 |
10721028 cmp instanceof CompareNEValueNumber and
10731029 value = innerValue
@@ -1078,14 +1034,13 @@ private module Cached {
10781034 }
10791035
10801036 private predicate unary_complex_eq (
1081- ValueNumber test , Operand op , int k , boolean areEqual , boolean inNonZeroCase ,
1082- AbstractValue value
1037+ ValueNumber test , Operand op , int k , boolean areEqual , AbstractValue value
10831038 ) {
1084- unary_sub_eq ( test , op , k , areEqual , inNonZeroCase , value )
1039+ unary_sub_eq ( test , op , k , areEqual , value )
10851040 or
1086- unary_add_eq ( test , op , k , areEqual , inNonZeroCase , value )
1041+ unary_add_eq ( test , op , k , areEqual , value )
10871042 or
1088- unary_builtin_expect_eq ( test , op , k , areEqual , inNonZeroCase , value )
1043+ unary_builtin_expect_eq ( test , op , k , areEqual , value )
10891044 }
10901045
10911046 /*
@@ -1347,20 +1302,17 @@ private module Cached {
13471302
13481303 // op - x == c => op == (c+x)
13491304 private predicate unary_sub_eq (
1350- ValueNumber test , Operand op , int k , boolean areEqual , boolean inNonZeroCase ,
1351- AbstractValue value
1305+ ValueNumber test , Operand op , int k , boolean areEqual , AbstractValue value
13521306 ) {
1353- inNonZeroCase = false and
13541307 exists ( SubInstruction sub , int c , int x |
1355- unary_compares_eq ( test , sub .getAUse ( ) , c , areEqual , inNonZeroCase , value ) and
1308+ unary_compares_eq ( test , sub .getAUse ( ) , c , areEqual , value ) and
13561309 op = sub .getLeftOperand ( ) and
13571310 x = int_value ( sub .getRight ( ) ) and
13581311 k = c + x
13591312 )
13601313 or
1361- inNonZeroCase = false and
13621314 exists ( PointerSubInstruction sub , int c , int x |
1363- unary_compares_eq ( test , sub .getAUse ( ) , c , areEqual , inNonZeroCase , value ) and
1315+ unary_compares_eq ( test , sub .getAUse ( ) , c , areEqual , value ) and
13641316 op = sub .getLeftOperand ( ) and
13651317 x = int_value ( sub .getRight ( ) ) and
13661318 k = c + x
@@ -1415,12 +1367,10 @@ private module Cached {
14151367
14161368 // left + x == right + c => left == right + (c-x)
14171369 private predicate unary_add_eq (
1418- ValueNumber test , Operand left , int k , boolean areEqual , boolean inNonZeroCase ,
1419- AbstractValue value
1370+ ValueNumber test , Operand left , int k , boolean areEqual , AbstractValue value
14201371 ) {
1421- inNonZeroCase = false and
14221372 exists ( AddInstruction lhs , int c , int x |
1423- unary_compares_eq ( test , lhs .getAUse ( ) , c , areEqual , inNonZeroCase , value ) and
1373+ unary_compares_eq ( test , lhs .getAUse ( ) , c , areEqual , value ) and
14241374 (
14251375 left = lhs .getLeftOperand ( ) and x = int_value ( lhs .getRight ( ) )
14261376 or
@@ -1429,9 +1379,8 @@ private module Cached {
14291379 k = c - x
14301380 )
14311381 or
1432- inNonZeroCase = false and
14331382 exists ( PointerAddInstruction lhs , int c , int x |
1434- unary_compares_eq ( test , lhs .getAUse ( ) , c , areEqual , inNonZeroCase , value ) and
1383+ unary_compares_eq ( test , lhs .getAUse ( ) , c , areEqual , value ) and
14351384 (
14361385 left = lhs .getLeftOperand ( ) and x = int_value ( lhs .getRight ( ) )
14371386 or
0 commit comments