@@ -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) {
@@ -2514,9 +2548,9 @@ static bool interp__builtin_is_within_lifetime(InterpState &S, CodePtr OpPC,
25142548 return true ;
25152549}
25162550
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) {
25202554 assert (Call->getNumArgs () == 2 );
25212555
25222556 // Single integer case.
@@ -2553,6 +2587,8 @@ static bool interp__builtin_elementwise_sat(InterpState &S, CodePtr OpPC,
25532587 const Pointer &LHS = S.Stk .pop <Pointer>();
25542588 const Pointer &Dst = S.Stk .peek <Pointer>();
25552589 PrimType ElemT = *S.getContext ().classify (VT->getElementType ());
2590+ bool DestUnsigned =
2591+ VT->getElementType ()->isUnsignedIntegerOrEnumerationType ();
25562592 unsigned NumElems = VT->getNumElements ();
25572593 for (unsigned I = 0 ; I != NumElems; ++I) {
25582594 APSInt Elem1;
@@ -2586,6 +2622,34 @@ static bool interp__builtin_elementwise_sat(InterpState &S, CodePtr OpPC,
25862622 Result = APSInt (llvm::APIntOps::mulhs (Elem1, Elem2),
25872623 /* isUnsigned=*/ false );
25882624 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 ;
25892653 default :
25902654 llvm_unreachable (" Wrong builtin ID" );
25912655 }
@@ -3232,7 +3296,17 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
32323296 case clang::X86::BI__builtin_ia32_pmulhw128:
32333297 case clang::X86::BI__builtin_ia32_pmulhw256:
32343298 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);
32363310
32373311 case Builtin::BI__builtin_elementwise_max:
32383312 case Builtin::BI__builtin_elementwise_min:
0 commit comments