@@ -797,6 +797,19 @@ private module Cached {
797797 Instruction getSuccessor ( CaseEdge kind ) { result = switch .getSuccessor ( kind ) }
798798 }
799799
800+ /**
801+ * A value number such that at least one of the instructions provides
802+ * the operand to a `ConditionalBranchInstruction`.
803+ */
804+ private class ConditionalBranchConditionValueNumber extends ValueNumber {
805+ ConditionalBranchInstruction branch ;
806+
807+ pragma [ nomagic]
808+ ConditionalBranchConditionValueNumber ( ) { this .getAnInstruction ( ) = branch .getCondition ( ) }
809+
810+ Operand getConditionOperand ( ) { result = branch .getConditionOperand ( ) }
811+ }
812+
800813 private class BuiltinExpectCallValueNumber extends ValueNumber {
801814 BuiltinExpectCallInstruction instr ;
802815
@@ -895,55 +908,6 @@ private module Cached {
895908 value .( BooleanValue ) .getValue ( ) = false
896909 }
897910
898- /**
899- * Holds if `op` is an operand that is eventually used in a unary comparison
900- * with a constant.
901- */
902- private predicate isRelevantUnaryComparisonOperand ( Operand op ) {
903- // Base case: `op` is an operand of a `CompareEQInstruction` or `CompareNEInstruction`,
904- // and the other operand is a constant.
905- exists ( CompareInstruction eq , Instruction instr |
906- eq .hasOperands ( op , instr .getAUse ( ) ) and
907- exists ( int_value ( instr ) )
908- |
909- eq instanceof CompareEQInstruction
910- or
911- eq instanceof CompareNEInstruction
912- )
913- or
914- // C doesn't have int-to-bool conversions, so `if(x)` will just generate:
915- // r2_1(glval<int>) = VariableAddress[x]
916- // r2_2(int) = Load[x] : &:r2_1, m1_6
917- // v2_3(void) = ConditionalBranch : r2_2
918- exists ( ConditionalBranchInstruction branch | branch .getConditionOperand ( ) = op )
919- or
920- // If `!x` is a relevant unary comparison then so is `x`.
921- exists ( LogicalNotInstruction logicalNot |
922- isRelevantUnaryComparisonOperand ( unique( | | logicalNot .getAUse ( ) ) ) and
923- logicalNot .getUnaryOperand ( ) = op
924- )
925- or
926- // If `y` is a relevant unary comparison and `y = x` then so is `x`.
927- not op .isDefinitionInexact ( ) and
928- exists ( CopyInstruction copy |
929- isRelevantUnaryComparisonOperand ( unique( | | copy .getAUse ( ) ) ) and
930- op = copy .getSourceValueOperand ( )
931- )
932- or
933- // If phi(x1, x2) is a relevant unary comparison then so are `x1` and `x2`.
934- not op .isDefinitionInexact ( ) and
935- exists ( PhiInstruction phi |
936- isRelevantUnaryComparisonOperand ( unique( | | phi .getAUse ( ) ) ) and
937- op = phi .getAnInputOperand ( )
938- )
939- or
940- // If `__builtin_expect(x)` is a relevant unary comparison then so is `x`.
941- exists ( BuiltinExpectCallInstruction call |
942- isRelevantUnaryComparisonOperand ( unique( | | call .getAUse ( ) ) ) and
943- op = call .getConditionOperand ( )
944- )
945- }
946-
947911 /** Rearrange various simple comparisons into `op == k` form. */
948912 private predicate unary_simple_comparison_eq (
949913 ValueNumber test , Operand op , int k , AbstractValue value
@@ -956,14 +920,23 @@ private module Cached {
956920 case .getValue ( ) .toInt ( ) = k
957921 )
958922 or
959- isRelevantUnaryComparisonOperand ( op ) and
960- op .getDef ( ) = test .getAnInstruction ( ) and
961- (
962- k = 1 and
963- value .( BooleanValue ) .getValue ( ) = true
923+ exists ( Instruction const | int_value ( const ) = k |
924+ value .( BooleanValue ) .getValue ( ) = true and
925+ test .( CompareEQValueNumber ) .hasOperands ( op , const .getAUse ( ) )
964926 or
927+ value .( BooleanValue ) .getValue ( ) = false and
928+ test .( CompareNEValueNumber ) .hasOperands ( op , const .getAUse ( ) )
929+ )
930+ or
931+ test .( ConditionalBranchConditionValueNumber ) .getConditionOperand ( ) = op and
932+ // Don't include comparisons since these are already included in the binary relation.
933+ not test instanceof CompareValueNumber and
934+ (
965935 k = 0 and
966936 value .( BooleanValue ) .getValue ( ) = false
937+ or
938+ k = 1 and
939+ value .( BooleanValue ) .getValue ( ) = true
967940 )
968941 }
969942
0 commit comments