@@ -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 NumElems = Val.getNumElems ();
149+
150+ // Each element is one bit, so create an integer with NumElts bits.
151+ llvm::APSInt Result (NumElems, 0 );
152+ for (unsigned I = 0 ; I != NumElems; ++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) {
@@ -643,8 +659,14 @@ static bool interp__builtin_abs(InterpState &S, CodePtr OpPC,
643659static bool interp__builtin_popcount (InterpState &S, CodePtr OpPC,
644660 const InterpFrame *Frame,
645661 const CallExpr *Call) {
646- PrimType ArgT = *S.getContext ().classify (Call->getArg (0 )->getType ());
647- APSInt Val = popToAPSInt (S.Stk , ArgT);
662+ APSInt Val;
663+ if (Call->getArg (0 )->getType ()->isExtVectorBoolType ()) {
664+ const Pointer &Arg = S.Stk .pop <Pointer>();
665+ Val = convertBoolVectorToInt (Arg);
666+ } else {
667+ PrimType ArgT = *S.getContext ().classify (Call->getArg (0 )->getType ());
668+ Val = popToAPSInt (S.Stk , ArgT);
669+ }
648670 pushInteger (S, Val.popcount (), Call->getType ());
649671 return true ;
650672}
@@ -940,8 +962,14 @@ static bool interp__builtin_clz(InterpState &S, CodePtr OpPC,
940962 PrimType FallbackT = *S.getContext ().classify (Call->getArg (1 ));
941963 Fallback = popToAPSInt (S.Stk , FallbackT);
942964 }
943- PrimType ValT = *S.getContext ().classify (Call->getArg (0 ));
944- const APSInt &Val = popToAPSInt (S.Stk , ValT);
965+ APSInt Val;
966+ if (Call->getArg (0 )->getType ()->isExtVectorBoolType ()) {
967+ const Pointer &Arg = S.Stk .pop <Pointer>();
968+ Val = convertBoolVectorToInt (Arg);
969+ } else {
970+ PrimType ValT = *S.getContext ().classify (Call->getArg (0 ));
971+ Val = popToAPSInt (S.Stk , ValT);
972+ }
945973
946974 // When the argument is 0, the result of GCC builtins is undefined, whereas
947975 // for Microsoft intrinsics, the result is the bit-width of the argument.
@@ -971,8 +999,14 @@ static bool interp__builtin_ctz(InterpState &S, CodePtr OpPC,
971999 PrimType FallbackT = *S.getContext ().classify (Call->getArg (1 ));
9721000 Fallback = popToAPSInt (S.Stk , FallbackT);
9731001 }
974- PrimType ValT = *S.getContext ().classify (Call->getArg (0 ));
975- const APSInt &Val = popToAPSInt (S.Stk , ValT);
1002+ APSInt Val;
1003+ if (Call->getArg (0 )->getType ()->isExtVectorBoolType ()) {
1004+ const Pointer &Arg = S.Stk .pop <Pointer>();
1005+ Val = convertBoolVectorToInt (Arg);
1006+ } else {
1007+ PrimType ValT = *S.getContext ().classify (Call->getArg (0 ));
1008+ Val = popToAPSInt (S.Stk , ValT);
1009+ }
9761010
9771011 if (Val == 0 ) {
9781012 if (Fallback) {
0 commit comments