@@ -923,12 +923,68 @@ private predicate unary_simple_comparison_eq(
923923 )
924924}
925925
926+ /** A call to the builtin operation `__builtin_expect`. */
927+ private class BuiltinExpectCallInstruction extends CallInstruction {
928+ BuiltinExpectCallInstruction ( ) { this .getStaticCallTarget ( ) .hasName ( "__builtin_expect" ) }
929+ }
930+
931+ /**
932+ * Holds if `left == right + k` is `areEqual` if `cmp` evaluates to `value`,
933+ * and `cmp` is nested inside a call to `__builtin_expect`.
934+ */
935+ private predicate builtin_expect_eq (
936+ CompareInstruction cmp , Operand left , Operand right , int k , boolean areEqual , AbstractValue value
937+ ) {
938+ exists (
939+ BuiltinExpectCallInstruction call , ConvertInstruction arg , Instruction const ,
940+ AbstractValue innerValue
941+ |
942+ int_value ( const ) = 0 and
943+ cmp .hasOperands ( call .getAUse ( ) , const .getAUse ( ) ) and
944+ arg = call .getArgument ( 0 ) and
945+ compares_eq ( arg .getUnary ( ) , left , right , k , areEqual , innerValue )
946+ |
947+ cmp instanceof CompareNEInstruction and
948+ value = innerValue
949+ or
950+ cmp instanceof CompareEQInstruction and
951+ value .getDualValue ( ) = innerValue
952+ )
953+ }
954+
926955private predicate complex_eq (
927956 CompareInstruction cmp , Operand left , Operand right , int k , boolean areEqual , AbstractValue value
928957) {
929958 sub_eq ( cmp , left , right , k , areEqual , value )
930959 or
931960 add_eq ( cmp , left , right , k , areEqual , value )
961+ or
962+ builtin_expect_eq ( cmp , left , right , k , areEqual , value )
963+ }
964+
965+ /**
966+ * Holds if `op == k` is `areEqual` if `cmp` evaluates to `value`, and
967+ * `cmp` is nested inside a call to `__builtin_expect`.
968+ */
969+ private predicate unary_builtin_expect_eq (
970+ CompareInstruction cmp , Operand op , int k , boolean areEqual , boolean inNonZeroCase ,
971+ AbstractValue value
972+ ) {
973+ exists (
974+ BuiltinExpectCallInstruction call , ConvertInstruction arg , Instruction const ,
975+ AbstractValue innerValue
976+ |
977+ int_value ( const ) = 0 and
978+ cmp .hasOperands ( call .getAUse ( ) , const .getAUse ( ) ) and
979+ arg = call .getArgument ( 0 ) and
980+ unary_compares_eq ( arg .getUnary ( ) , op , k , areEqual , inNonZeroCase , innerValue )
981+ |
982+ cmp instanceof CompareNEInstruction and
983+ value = innerValue
984+ or
985+ cmp instanceof CompareEQInstruction and
986+ value .getDualValue ( ) = innerValue
987+ )
932988}
933989
934990private predicate unary_complex_eq (
@@ -937,6 +993,8 @@ private predicate unary_complex_eq(
937993 unary_sub_eq ( test , op , k , areEqual , inNonZeroCase , value )
938994 or
939995 unary_add_eq ( test , op , k , areEqual , inNonZeroCase , value )
996+ or
997+ unary_builtin_expect_eq ( test , op , k , areEqual , inNonZeroCase , value )
940998}
941999
9421000/*
0 commit comments