@@ -923,12 +923,68 @@ private predicate unary_simple_comparison_eq(
923
923
)
924
924
}
925
925
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
+
926
955
private predicate complex_eq (
927
956
CompareInstruction cmp , Operand left , Operand right , int k , boolean areEqual , AbstractValue value
928
957
) {
929
958
sub_eq ( cmp , left , right , k , areEqual , value )
930
959
or
931
960
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
+ )
932
988
}
933
989
934
990
private predicate unary_complex_eq (
@@ -937,6 +993,8 @@ private predicate unary_complex_eq(
937
993
unary_sub_eq ( test , op , k , areEqual , inNonZeroCase , value )
938
994
or
939
995
unary_add_eq ( test , op , k , areEqual , inNonZeroCase , value )
996
+ or
997
+ unary_builtin_expect_eq ( test , op , k , areEqual , inNonZeroCase , value )
940
998
}
941
999
942
1000
/*
0 commit comments