@@ -1380,32 +1380,6 @@ static bool interp__builtin_ia32_bzhi(InterpState &S, CodePtr OpPC,
13801380 return true ;
13811381}
13821382
1383- static bool interp__builtin_ia32_lzcnt (InterpState &S, CodePtr OpPC,
1384- const InterpFrame *Frame,
1385- const CallExpr *Call) {
1386- QualType CallType = Call->getType ();
1387- if (!CallType->isIntegerType () ||
1388- !Call->getArg (0 )->getType ()->isIntegerType ())
1389- return false ;
1390-
1391- APSInt Val = popToAPSInt (S, Call->getArg (0 ));
1392- pushInteger (S, Val.countLeadingZeros (), CallType);
1393- return true ;
1394- }
1395-
1396- static bool interp__builtin_ia32_tzcnt (InterpState &S, CodePtr OpPC,
1397- const InterpFrame *Frame,
1398- const CallExpr *Call) {
1399- QualType CallType = Call->getType ();
1400- if (!CallType->isIntegerType () ||
1401- !Call->getArg (0 )->getType ()->isIntegerType ())
1402- return false ;
1403-
1404- APSInt Val = popToAPSInt (S, Call->getArg (0 ));
1405- pushInteger (S, Val.countTrailingZeros (), CallType);
1406- return true ;
1407- }
1408-
14091383static bool interp__builtin_ia32_pdep (InterpState &S, CodePtr OpPC,
14101384 const InterpFrame *Frame,
14111385 const CallExpr *Call) {
@@ -2551,6 +2525,24 @@ static bool interp__builtin_is_within_lifetime(InterpState &S, CodePtr OpPC,
25512525 return true ;
25522526}
25532527
2528+ static bool interp__builtin_elementwise_int_unaryop (
2529+ InterpState &S, CodePtr OpPC, const CallExpr *Call,
2530+ llvm::function_ref<APInt(const APSInt &)> Fn) {
2531+ assert (Call->getNumArgs () == 1 );
2532+ assert (Call->getType ()->isIntegerType ());
2533+
2534+ // Single integer case.
2535+ if (!Call->getArg (0 )->getType ()->isVectorType ()) {
2536+ APSInt Src = popToAPSInt (S, Call->getArg (0 ));
2537+ APInt Result = Fn (Src);
2538+ pushInteger (S, APSInt (std::move (Result), !Src.isSigned ()), Call->getType ());
2539+ return true ;
2540+ }
2541+
2542+ // TODO: Add vector integer handling.
2543+ return false ;
2544+ }
2545+
25542546static bool interp__builtin_elementwise_int_binop (
25552547 InterpState &S, CodePtr OpPC, const CallExpr *Call,
25562548 llvm::function_ref<APInt(const APSInt &, const APSInt &)> Fn) {
@@ -3283,12 +3275,18 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
32833275 case clang::X86::BI__builtin_ia32_lzcnt_u16:
32843276 case clang::X86::BI__builtin_ia32_lzcnt_u32:
32853277 case clang::X86::BI__builtin_ia32_lzcnt_u64:
3286- return interp__builtin_ia32_lzcnt (S, OpPC, Frame, Call);
3278+ return interp__builtin_elementwise_int_unaryop (
3279+ S, OpPC, Call, [](const APSInt &Src) {
3280+ return APInt (Src.getBitWidth (), Src.countLeadingZeros ());
3281+ });
32873282
32883283 case clang::X86::BI__builtin_ia32_tzcnt_u16:
32893284 case clang::X86::BI__builtin_ia32_tzcnt_u32:
32903285 case clang::X86::BI__builtin_ia32_tzcnt_u64:
3291- return interp__builtin_ia32_tzcnt (S, OpPC, Frame, Call);
3286+ return interp__builtin_elementwise_int_unaryop (
3287+ S, OpPC, Call, [](const APSInt &Src) {
3288+ return APInt (Src.getBitWidth (), Src.countTrailingZeros ());
3289+ });
32923290
32933291 case clang::X86::BI__builtin_ia32_pdep_si:
32943292 case clang::X86::BI__builtin_ia32_pdep_di:
0 commit comments