@@ -1626,51 +1626,6 @@ static bool interp__builtin_elementwise_abs(InterpState &S, CodePtr OpPC,
16261626 return true ;
16271627}
16281628
1629- // / Can be called with an integer or vector as the first and only parameter.
1630- static bool interp__builtin_elementwise_popcount (InterpState &S, CodePtr OpPC,
1631- const InterpFrame *Frame,
1632- const CallExpr *Call,
1633- unsigned BuiltinID) {
1634- assert (Call->getNumArgs () == 1 );
1635- if (Call->getArg (0 )->getType ()->isIntegerType ()) {
1636- APSInt Val = popToAPSInt (S, Call->getArg (0 ));
1637-
1638- if (BuiltinID == Builtin::BI__builtin_elementwise_popcount) {
1639- pushInteger (S, Val.popcount (), Call->getType ());
1640- } else {
1641- pushInteger (S, Val.reverseBits (), Call->getType ());
1642- }
1643- return true ;
1644- }
1645- // Otherwise, the argument must be a vector.
1646- assert (Call->getArg (0 )->getType ()->isVectorType ());
1647- const Pointer &Arg = S.Stk .pop <Pointer>();
1648- assert (Arg.getFieldDesc ()->isPrimitiveArray ());
1649- const Pointer &Dst = S.Stk .peek <Pointer>();
1650- assert (Dst.getFieldDesc ()->isPrimitiveArray ());
1651- assert (Arg.getFieldDesc ()->getNumElems () ==
1652- Dst.getFieldDesc ()->getNumElems ());
1653-
1654- QualType ElemType = Arg.getFieldDesc ()->getElemQualType ();
1655- PrimType ElemT = *S.getContext ().classify (ElemType);
1656- unsigned NumElems = Arg.getNumElems ();
1657-
1658- // FIXME: Reading from uninitialized vector elements?
1659- for (unsigned I = 0 ; I != NumElems; ++I) {
1660- INT_TYPE_SWITCH_NO_BOOL (ElemT, {
1661- if (BuiltinID == Builtin::BI__builtin_elementwise_popcount) {
1662- Dst.elem <T>(I) = T::from (Arg.elem <T>(I).toAPSInt ().popcount ());
1663- } else {
1664- Dst.elem <T>(I) =
1665- T::from (Arg.elem <T>(I).toAPSInt ().reverseBits ().getZExtValue ());
1666- }
1667- });
1668- }
1669- Dst.initializeAllElements ();
1670-
1671- return true ;
1672- }
1673-
16741629// / Can be called with an integer or vector as the first and only parameter.
16751630static bool interp__builtin_elementwise_countzeroes (InterpState &S,
16761631 CodePtr OpPC,
@@ -2407,18 +2362,39 @@ static bool interp__builtin_elementwise_int_unaryop(
24072362 InterpState &S, CodePtr OpPC, const CallExpr *Call,
24082363 llvm::function_ref<APInt(const APSInt &)> Fn) {
24092364 assert (Call->getNumArgs () == 1 );
2410- assert (Call->getType ()->isIntegerType ());
24112365
24122366 // Single integer case.
24132367 if (!Call->getArg (0 )->getType ()->isVectorType ()) {
2368+ assert (Call->getType ()->isIntegerType ());
24142369 APSInt Src = popToAPSInt (S, Call->getArg (0 ));
24152370 APInt Result = Fn (Src);
24162371 pushInteger (S, APSInt (std::move (Result), !Src.isSigned ()), Call->getType ());
24172372 return true ;
24182373 }
24192374
2420- // TODO: Add vector integer handling.
2421- return false ;
2375+ // Vector case.
2376+ const Pointer &Arg = S.Stk .pop <Pointer>();
2377+ assert (Arg.getFieldDesc ()->isPrimitiveArray ());
2378+ const Pointer &Dst = S.Stk .peek <Pointer>();
2379+ assert (Dst.getFieldDesc ()->isPrimitiveArray ());
2380+ assert (Arg.getFieldDesc ()->getNumElems () ==
2381+ Dst.getFieldDesc ()->getNumElems ());
2382+
2383+ QualType ElemType = Arg.getFieldDesc ()->getElemQualType ();
2384+ PrimType ElemT = *S.getContext ().classify (ElemType);
2385+ unsigned NumElems = Arg.getNumElems ();
2386+ bool DestUnsigned = Call->getType ()->isUnsignedIntegerOrEnumerationType ();
2387+
2388+ for (unsigned I = 0 ; I != NumElems; ++I) {
2389+ INT_TYPE_SWITCH_NO_BOOL (ElemT, {
2390+ APSInt Src = Arg.elem <T>(I).toAPSInt ();
2391+ APInt Result = Fn (Src);
2392+ Dst.elem <T>(I) = static_cast <T>(APSInt (std::move (Result), DestUnsigned));
2393+ });
2394+ }
2395+ Dst.initializeAllElements ();
2396+
2397+ return true ;
24222398}
24232399
24242400static bool interp__builtin_elementwise_int_binop (
@@ -4212,9 +4188,13 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
42124188 return interp__builtin_vector_reduce (S, OpPC, Call, BuiltinID);
42134189
42144190 case Builtin::BI__builtin_elementwise_popcount:
4191+ return interp__builtin_elementwise_int_unaryop (
4192+ S, OpPC, Call, [](const APSInt &Src) {
4193+ return APInt (Src.getBitWidth (), Src.popcount ());
4194+ });
42154195 case Builtin::BI__builtin_elementwise_bitreverse:
4216- return interp__builtin_elementwise_popcount (S, OpPC, Frame, Call,
4217- BuiltinID );
4196+ return interp__builtin_elementwise_int_unaryop (
4197+ S, OpPC, Call, []( const APSInt &Src) { return Src. reverseBits (); } );
42184198
42194199 case Builtin::BI__builtin_elementwise_abs:
42204200 return interp__builtin_elementwise_abs (S, OpPC, Frame, Call, BuiltinID);
0 commit comments