@@ -141,6 +141,22 @@ static void diagnoseNonConstexprBuiltin(InterpState &S, CodePtr OpPC,
141141 S.CCEDiag (Loc, diag::note_invalid_subexpr_in_const_expr);
142142}
143143
144+ static llvm::APSInt convertBoolVectorToInt (const Pointer &Val) {
145+ assert (Val.getFieldDesc ()->isPrimitiveArray () &&
146+ Val.getFieldDesc ()->getElemQualType ()->isBooleanType () &&
147+ " Not a boolean vector" );
148+ unsigned NumElts = Val.getNumElems ();
149+
150+ // Each element is one bit, so create an integer with NumElts bits.
151+ llvm::APSInt Result (NumElts, 0 );
152+ for (unsigned I = 0 ; I < NumElts; ++I) {
153+ if (Val.elem <bool >(I))
154+ Result.setBit (I);
155+ }
156+
157+ return Result;
158+ }
159+
144160static bool interp__builtin_is_constant_evaluated (InterpState &S, CodePtr OpPC,
145161 const InterpFrame *Frame,
146162 const CallExpr *Call) {
@@ -638,8 +654,14 @@ static bool interp__builtin_abs(InterpState &S, CodePtr OpPC,
638654static bool interp__builtin_popcount (InterpState &S, CodePtr OpPC,
639655 const InterpFrame *Frame,
640656 const CallExpr *Call) {
641- PrimType ArgT = *S.getContext ().classify (Call->getArg (0 )->getType ());
642- APSInt Val = popToAPSInt (S.Stk , ArgT);
657+ APSInt Val;
658+ if (Call->getArg (0 )->getType ()->isExtVectorBoolType ()) {
659+ const Pointer &Arg = S.Stk .pop <Pointer>();
660+ Val = convertBoolVectorToInt (Arg);
661+ } else {
662+ PrimType ArgT = *S.getContext ().classify (Call->getArg (0 )->getType ());
663+ Val = popToAPSInt (S.Stk , ArgT);
664+ }
643665 pushInteger (S, Val.popcount (), Call->getType ());
644666 return true ;
645667}
@@ -935,8 +957,14 @@ static bool interp__builtin_clz(InterpState &S, CodePtr OpPC,
935957 PrimType FallbackT = *S.getContext ().classify (Call->getArg (1 ));
936958 Fallback = popToAPSInt (S.Stk , FallbackT);
937959 }
938- PrimType ValT = *S.getContext ().classify (Call->getArg (0 ));
939- const APSInt &Val = popToAPSInt (S.Stk , ValT);
960+ APSInt Val;
961+ if (Call->getArg (0 )->getType ()->isExtVectorBoolType ()) {
962+ const Pointer &Arg = S.Stk .pop <Pointer>();
963+ Val = convertBoolVectorToInt (Arg);
964+ } else {
965+ PrimType ValT = *S.getContext ().classify (Call->getArg (0 ));
966+ Val = popToAPSInt (S.Stk , ValT);
967+ }
940968
941969 // When the argument is 0, the result of GCC builtins is undefined, whereas
942970 // for Microsoft intrinsics, the result is the bit-width of the argument.
@@ -966,8 +994,14 @@ static bool interp__builtin_ctz(InterpState &S, CodePtr OpPC,
966994 PrimType FallbackT = *S.getContext ().classify (Call->getArg (1 ));
967995 Fallback = popToAPSInt (S.Stk , FallbackT);
968996 }
969- PrimType ValT = *S.getContext ().classify (Call->getArg (0 ));
970- const APSInt &Val = popToAPSInt (S.Stk , ValT);
997+ APSInt Val;
998+ if (Call->getArg (0 )->getType ()->isExtVectorBoolType ()) {
999+ const Pointer &Arg = S.Stk .pop <Pointer>();
1000+ Val = convertBoolVectorToInt (Arg);
1001+ } else {
1002+ PrimType ValT = *S.getContext ().classify (Call->getArg (0 ));
1003+ Val = popToAPSInt (S.Stk , ValT);
1004+ }
9711005
9721006 if (Val == 0 ) {
9731007 if (Fallback) {
0 commit comments