@@ -141,6 +141,22 @@ static void diagnoseNonConstexprBuiltin(InterpState &S, CodePtr OpPC,
141
141
S.CCEDiag (Loc, diag::note_invalid_subexpr_in_const_expr);
142
142
}
143
143
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
+
144
160
static bool interp__builtin_is_constant_evaluated (InterpState &S, CodePtr OpPC,
145
161
const InterpFrame *Frame,
146
162
const CallExpr *Call) {
@@ -643,8 +659,14 @@ static bool interp__builtin_abs(InterpState &S, CodePtr OpPC,
643
659
static bool interp__builtin_popcount (InterpState &S, CodePtr OpPC,
644
660
const InterpFrame *Frame,
645
661
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
+ }
648
670
pushInteger (S, Val.popcount (), Call->getType ());
649
671
return true ;
650
672
}
@@ -940,8 +962,14 @@ static bool interp__builtin_clz(InterpState &S, CodePtr OpPC,
940
962
PrimType FallbackT = *S.getContext ().classify (Call->getArg (1 ));
941
963
Fallback = popToAPSInt (S.Stk , FallbackT);
942
964
}
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
+ }
945
973
946
974
// When the argument is 0, the result of GCC builtins is undefined, whereas
947
975
// 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,
971
999
PrimType FallbackT = *S.getContext ().classify (Call->getArg (1 ));
972
1000
Fallback = popToAPSInt (S.Stk , FallbackT);
973
1001
}
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
+ }
976
1010
977
1011
if (Val == 0 ) {
978
1012
if (Fallback) {
0 commit comments