@@ -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) {
@@ -2514,9 +2548,9 @@ static bool interp__builtin_is_within_lifetime(InterpState &S, CodePtr OpPC,
2514
2548
return true ;
2515
2549
}
2516
2550
2517
- static bool interp__builtin_elementwise_sat (InterpState &S, CodePtr OpPC,
2518
- const CallExpr *Call,
2519
- unsigned BuiltinID) {
2551
+ static bool interp__builtin_elementwise_int_binop (InterpState &S, CodePtr OpPC,
2552
+ const CallExpr *Call,
2553
+ unsigned BuiltinID) {
2520
2554
assert (Call->getNumArgs () == 2 );
2521
2555
2522
2556
// Single integer case.
@@ -2553,6 +2587,8 @@ static bool interp__builtin_elementwise_sat(InterpState &S, CodePtr OpPC,
2553
2587
const Pointer &LHS = S.Stk .pop <Pointer>();
2554
2588
const Pointer &Dst = S.Stk .peek <Pointer>();
2555
2589
PrimType ElemT = *S.getContext ().classify (VT->getElementType ());
2590
+ bool DestUnsigned =
2591
+ VT->getElementType ()->isUnsignedIntegerOrEnumerationType ();
2556
2592
unsigned NumElems = VT->getNumElements ();
2557
2593
for (unsigned I = 0 ; I != NumElems; ++I) {
2558
2594
APSInt Elem1;
@@ -2586,6 +2622,34 @@ static bool interp__builtin_elementwise_sat(InterpState &S, CodePtr OpPC,
2586
2622
Result = APSInt (llvm::APIntOps::mulhs (Elem1, Elem2),
2587
2623
/* isUnsigned=*/ false );
2588
2624
break ;
2625
+ case clang::X86::BI__builtin_ia32_psllv2di:
2626
+ case clang::X86::BI__builtin_ia32_psllv4di:
2627
+ case clang::X86::BI__builtin_ia32_psllv4si:
2628
+ case clang::X86::BI__builtin_ia32_psllv8si:
2629
+ if (Elem2.uge (Elem2.getBitWidth ())) {
2630
+ Result = APSInt (APInt::getZero (Elem2.getBitWidth ()), DestUnsigned);
2631
+ break ;
2632
+ }
2633
+ Result = APSInt (Elem1.shl (Elem2.getZExtValue ()), DestUnsigned);
2634
+ break ;
2635
+ case clang::X86::BI__builtin_ia32_psrav4si:
2636
+ case clang::X86::BI__builtin_ia32_psrav8si:
2637
+ if (Elem2.uge (Elem2.getBitWidth ())) {
2638
+ Result = APSInt (Elem1.ashr (Elem2.getBitWidth () - 1 ), DestUnsigned);
2639
+ break ;
2640
+ }
2641
+ Result = APSInt (Elem1.ashr (Elem2.getZExtValue ()), DestUnsigned);
2642
+ break ;
2643
+ case clang::X86::BI__builtin_ia32_psrlv2di:
2644
+ case clang::X86::BI__builtin_ia32_psrlv4di:
2645
+ case clang::X86::BI__builtin_ia32_psrlv4si:
2646
+ case clang::X86::BI__builtin_ia32_psrlv8si:
2647
+ if (Elem2.uge (Elem2.getBitWidth ())) {
2648
+ Result = APSInt (APInt::getZero (Elem2.getBitWidth ()), DestUnsigned);
2649
+ break ;
2650
+ }
2651
+ Result = APSInt (Elem1.lshr (Elem2.getZExtValue ()), DestUnsigned);
2652
+ break ;
2589
2653
default :
2590
2654
llvm_unreachable (" Wrong builtin ID" );
2591
2655
}
@@ -3232,7 +3296,17 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
3232
3296
case clang::X86::BI__builtin_ia32_pmulhw128:
3233
3297
case clang::X86::BI__builtin_ia32_pmulhw256:
3234
3298
case clang::X86::BI__builtin_ia32_pmulhw512:
3235
- return interp__builtin_elementwise_sat (S, OpPC, Call, BuiltinID);
3299
+ case clang::X86::BI__builtin_ia32_psllv2di:
3300
+ case clang::X86::BI__builtin_ia32_psllv4di:
3301
+ case clang::X86::BI__builtin_ia32_psllv4si:
3302
+ case clang::X86::BI__builtin_ia32_psllv8si:
3303
+ case clang::X86::BI__builtin_ia32_psrav4si:
3304
+ case clang::X86::BI__builtin_ia32_psrav8si:
3305
+ case clang::X86::BI__builtin_ia32_psrlv2di:
3306
+ case clang::X86::BI__builtin_ia32_psrlv4di:
3307
+ case clang::X86::BI__builtin_ia32_psrlv4si:
3308
+ case clang::X86::BI__builtin_ia32_psrlv8si:
3309
+ return interp__builtin_elementwise_int_binop (S, OpPC, Call, BuiltinID);
3236
3310
3237
3311
case Builtin::BI__builtin_elementwise_max:
3238
3312
case Builtin::BI__builtin_elementwise_min:
0 commit comments