diff --git a/src/frontc/cabs2cil.ml b/src/frontc/cabs2cil.ml index 2f4dea79b..19c54a6f6 100644 --- a/src/frontc/cabs2cil.ml +++ b/src/frontc/cabs2cil.ml @@ -4752,6 +4752,22 @@ and doExp (asconst: bool) (* This expression is used as a constant *) prestype := intType | _ -> ignore (warn "Invalid call to builtin_types_compatible_p"); end + else if fv.vname = "__builtin_clzll" && asconst && isEmpty (!prechunk ()) then + begin + (* Constant-fold the argument and see if it is a constant *) + let countLeadingZeros (arg: cilint) pos = pos - Z.numbits arg + in + match !pargs with + [ arg ] -> begin + match constFold true arg with + (Const CInt (arg, kind, _)) -> + piscall := false; + pres := integer (countLeadingZeros arg 64); + prestype := intType + | _ -> () + end + | _ -> ignore (warn "Invalid call to __builtin_clzll"); + end end | _ -> () ); diff --git a/test/small1/builtin_clzll.c b/test/small1/builtin_clzll.c new file mode 100644 index 000000000..d3c749964 --- /dev/null +++ b/test/small1/builtin_clzll.c @@ -0,0 +1,11 @@ +struct S1 { + int x : __builtin_choose_expr(__builtin_clzll(1) == 63, 1, -1), + : __builtin_choose_expr(__builtin_clzll(2) == 62, 1, -1), + : __builtin_choose_expr(__builtin_clzll(4) == 61, 1, -1), + : __builtin_choose_expr(__builtin_clzll(1024) == 53, 1, -1), + : __builtin_choose_expr(__builtin_clzll(1024 * 1024) == 43, 1, -1); +} s1 = {0}; + +int main() { + return 0; +} \ No newline at end of file diff --git a/test/testcil.pl b/test/testcil.pl index 151a12652..9de7c7f2e 100644 --- a/test/testcil.pl +++ b/test/testcil.pl @@ -557,6 +557,7 @@ sub addToGroup { addTest("testrun/builtin4 "); addTest("test/builtin5 "); addTest("test/builtin6 "); +addTest("testrun/builtin_clzll "); addTest("test/sync-1 _GNUCC=1"); addTest("test/sync-2 _GNUCC=1"); addTest("test/sync-3 _GNUCC=1");