@@ -205,14 +205,19 @@ static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC,
205205
206206 if (A.isDummy () || B.isDummy ())
207207 return false ;
208+ if (!A.isBlockPointer () || !B.isBlockPointer ())
209+ return false ;
208210
209211 bool IsWide = ID == Builtin::BIwcscmp || ID == Builtin::BIwcsncmp ||
210212 ID == Builtin::BI__builtin_wcscmp ||
211213 ID == Builtin::BI__builtin_wcsncmp;
212214 assert (A.getFieldDesc ()->isPrimitiveArray ());
213215 assert (B.getFieldDesc ()->isPrimitiveArray ());
214216
215- assert (getElemType (A).getTypePtr () == getElemType (B).getTypePtr ());
217+ // Different element types shouldn't happen, but with casts they can.
218+ if (!S.getASTContext ().hasSameUnqualifiedType (getElemType (A), getElemType (B)))
219+ return false ;
220+
216221 PrimType ElemT = *S.getContext ().classify (getElemType (A));
217222
218223 auto returnResult = [&](int V) -> bool {
@@ -2778,6 +2783,40 @@ static bool interp__builtin_elementwise_fma(InterpState &S, CodePtr OpPC,
27782783 return true ;
27792784}
27802785
2786+ // / AVX512 predicated move: "Result = Mask[] ? LHS[] : RHS[]".
2787+ static bool interp__builtin_select (InterpState &S, CodePtr OpPC,
2788+ const CallExpr *Call) {
2789+ const Pointer &RHS = S.Stk .pop <Pointer>();
2790+ const Pointer &LHS = S.Stk .pop <Pointer>();
2791+ PrimType MaskT = *S.getContext ().classify (Call->getArg (0 ));
2792+ APSInt Mask = popToAPSInt (S.Stk , MaskT);
2793+ const Pointer &Dst = S.Stk .peek <Pointer>();
2794+
2795+ assert (LHS.getNumElems () == RHS.getNumElems ());
2796+ assert (LHS.getNumElems () == Dst.getNumElems ());
2797+ unsigned NumElems = LHS.getNumElems ();
2798+ PrimType ElemT = LHS.getFieldDesc ()->getPrimType ();
2799+ PrimType DstElemT = Dst.getFieldDesc ()->getPrimType ();
2800+
2801+ for (unsigned I = 0 ; I != NumElems; ++I) {
2802+ if (ElemT == PT_Float) {
2803+ assert (DstElemT == PT_Float);
2804+ Dst.elem <Floating>(I) =
2805+ Mask[I] ? LHS.elem <Floating>(I) : RHS.elem <Floating>(I);
2806+ } else {
2807+ APSInt Elem;
2808+ INT_TYPE_SWITCH (ElemT, {
2809+ Elem = Mask[I] ? LHS.elem <T>(I).toAPSInt () : RHS.elem <T>(I).toAPSInt ();
2810+ });
2811+ INT_TYPE_SWITCH_NO_BOOL (DstElemT,
2812+ { Dst.elem <T>(I) = static_cast <T>(Elem); });
2813+ }
2814+ }
2815+ Dst.initializeAllElements ();
2816+
2817+ return true ;
2818+ }
2819+
27812820bool InterpretBuiltin (InterpState &S, CodePtr OpPC, const CallExpr *Call,
27822821 uint32_t BuiltinID) {
27832822 if (!S.getASTContext ().BuiltinInfo .isConstantEvaluated (BuiltinID))
@@ -3210,9 +3249,36 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
32103249 case clang::X86::BI__builtin_ia32_pmuludq256:
32113250 case clang::X86::BI__builtin_ia32_pmuludq512:
32123251 return interp__builtin_ia32_pmul (S, OpPC, Call, BuiltinID);
3252+
32133253 case Builtin::BI__builtin_elementwise_fma:
32143254 return interp__builtin_elementwise_fma (S, OpPC, Call);
32153255
3256+ case X86::BI__builtin_ia32_selectb_128:
3257+ case X86::BI__builtin_ia32_selectb_256:
3258+ case X86::BI__builtin_ia32_selectb_512:
3259+ case X86::BI__builtin_ia32_selectw_128:
3260+ case X86::BI__builtin_ia32_selectw_256:
3261+ case X86::BI__builtin_ia32_selectw_512:
3262+ case X86::BI__builtin_ia32_selectd_128:
3263+ case X86::BI__builtin_ia32_selectd_256:
3264+ case X86::BI__builtin_ia32_selectd_512:
3265+ case X86::BI__builtin_ia32_selectq_128:
3266+ case X86::BI__builtin_ia32_selectq_256:
3267+ case X86::BI__builtin_ia32_selectq_512:
3268+ case X86::BI__builtin_ia32_selectph_128:
3269+ case X86::BI__builtin_ia32_selectph_256:
3270+ case X86::BI__builtin_ia32_selectph_512:
3271+ case X86::BI__builtin_ia32_selectpbf_128:
3272+ case X86::BI__builtin_ia32_selectpbf_256:
3273+ case X86::BI__builtin_ia32_selectpbf_512:
3274+ case X86::BI__builtin_ia32_selectps_128:
3275+ case X86::BI__builtin_ia32_selectps_256:
3276+ case X86::BI__builtin_ia32_selectps_512:
3277+ case X86::BI__builtin_ia32_selectpd_128:
3278+ case X86::BI__builtin_ia32_selectpd_256:
3279+ case X86::BI__builtin_ia32_selectpd_512:
3280+ return interp__builtin_select (S, OpPC, Call);
3281+
32163282 default :
32173283 S.FFDiag (S.Current ->getLocation (OpPC),
32183284 diag::note_invalid_subexpr_in_const_expr)
0 commit comments