@@ -666,16 +666,6 @@ static bool interp__builtin_abs(InterpState &S, CodePtr OpPC,
666666 return true ;
667667}
668668
669- static bool interp__builtin_knot (InterpState &S, CodePtr OpPC,
670- const InterpFrame *Frame,
671- const CallExpr *Call) {
672- APSInt Val =
673- popToAPSInt (S.Stk , *S.getContext ().classify (Call->getArg (0 )->getType ()));
674- APInt Result = ~Val;
675- pushInteger (S, APSInt (std::move (Result), true ), Call->getType ());
676- return true ;
677- }
678-
679669static bool interp__builtin_popcount (InterpState &S, CodePtr OpPC,
680670 const InterpFrame *Frame,
681671 const CallExpr *Call) {
@@ -1380,32 +1370,6 @@ static bool interp__builtin_ia32_bzhi(InterpState &S, CodePtr OpPC,
13801370 return true ;
13811371}
13821372
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-
14091373static bool interp__builtin_ia32_pdep (InterpState &S, CodePtr OpPC,
14101374 const InterpFrame *Frame,
14111375 const CallExpr *Call) {
@@ -2551,6 +2515,24 @@ static bool interp__builtin_is_within_lifetime(InterpState &S, CodePtr OpPC,
25512515 return true ;
25522516}
25532517
2518+ static bool interp__builtin_elementwise_int_unaryop (
2519+ InterpState &S, CodePtr OpPC, const CallExpr *Call,
2520+ llvm::function_ref<APInt(const APSInt &)> Fn) {
2521+ assert (Call->getNumArgs () == 1 );
2522+ assert (Call->getType ()->isIntegerType ());
2523+
2524+ // Single integer case.
2525+ if (!Call->getArg (0 )->getType ()->isVectorType ()) {
2526+ APSInt Src = popToAPSInt (S, Call->getArg (0 ));
2527+ APInt Result = Fn (Src);
2528+ pushInteger (S, APSInt (std::move (Result), !Src.isSigned ()), Call->getType ());
2529+ return true ;
2530+ }
2531+
2532+ // TODO: Add vector integer handling.
2533+ return false ;
2534+ }
2535+
25542536static bool interp__builtin_elementwise_int_binop (
25552537 InterpState &S, CodePtr OpPC, const CallExpr *Call,
25562538 llvm::function_ref<APInt(const APSInt &, const APSInt &)> Fn) {
@@ -3283,12 +3265,18 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
32833265 case clang::X86::BI__builtin_ia32_lzcnt_u16:
32843266 case clang::X86::BI__builtin_ia32_lzcnt_u32:
32853267 case clang::X86::BI__builtin_ia32_lzcnt_u64:
3286- return interp__builtin_ia32_lzcnt (S, OpPC, Frame, Call);
3268+ return interp__builtin_elementwise_int_unaryop (
3269+ S, OpPC, Call, [](const APSInt &Src) {
3270+ return APInt (Src.getBitWidth (), Src.countLeadingZeros ());
3271+ });
32873272
32883273 case clang::X86::BI__builtin_ia32_tzcnt_u16:
32893274 case clang::X86::BI__builtin_ia32_tzcnt_u32:
32903275 case clang::X86::BI__builtin_ia32_tzcnt_u64:
3291- return interp__builtin_ia32_tzcnt (S, OpPC, Frame, Call);
3276+ return interp__builtin_elementwise_int_unaryop (
3277+ S, OpPC, Call, [](const APSInt &Src) {
3278+ return APInt (Src.getBitWidth (), Src.countTrailingZeros ());
3279+ });
32923280
32933281 case clang::X86::BI__builtin_ia32_pdep_si:
32943282 case clang::X86::BI__builtin_ia32_pdep_di:
@@ -3661,7 +3649,8 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
36613649 case X86::BI__builtin_ia32_knothi:
36623650 case X86::BI__builtin_ia32_knotsi:
36633651 case X86::BI__builtin_ia32_knotdi:
3664- return interp__builtin_knot (S, OpPC, Frame, Call);
3652+ return interp__builtin_elementwise_int_unaryop (
3653+ S, OpPC, Call, [](const APSInt &Src) { return ~Src; });
36653654
36663655 case X86::BI__builtin_ia32_kaddqi:
36673656 case X86::BI__builtin_ia32_kaddhi:
0 commit comments