@@ -2778,6 +2778,40 @@ static bool interp__builtin_elementwise_fma(InterpState &S, CodePtr OpPC,
27782778 return true ;
27792779}
27802780
2781+ // / AVX512 predicated move: "Result = Mask[] ? LHS[] : RHS[]".
2782+ static bool interp__builtin_select (InterpState &S, CodePtr OpPC,
2783+ const CallExpr *Call) {
2784+ const Pointer &RHS = S.Stk .pop <Pointer>();
2785+ const Pointer &LHS = S.Stk .pop <Pointer>();
2786+ PrimType MaskT = *S.getContext ().classify (Call->getArg (0 ));
2787+ APSInt Mask = popToAPSInt (S.Stk , MaskT);
2788+ const Pointer &Dst = S.Stk .peek <Pointer>();
2789+
2790+ assert (LHS.getNumElems () == RHS.getNumElems ());
2791+ assert (LHS.getNumElems () == Dst.getNumElems ());
2792+ unsigned NumElems = LHS.getNumElems ();
2793+ PrimType ElemT = LHS.getFieldDesc ()->getPrimType ();
2794+ PrimType DstElemT = Dst.getFieldDesc ()->getPrimType ();
2795+
2796+ for (unsigned I = 0 ; I != NumElems; ++I) {
2797+ if (ElemT == PT_Float) {
2798+ assert (DstElemT == PT_Float);
2799+ Dst.elem <Floating>(I) =
2800+ Mask[I] ? LHS.elem <Floating>(I) : RHS.elem <Floating>(I);
2801+ } else {
2802+ APSInt Elem;
2803+ INT_TYPE_SWITCH (ElemT, {
2804+ Elem = Mask[I] ? LHS.elem <T>(I).toAPSInt () : RHS.elem <T>(I).toAPSInt ();
2805+ });
2806+ INT_TYPE_SWITCH_NO_BOOL (DstElemT,
2807+ { Dst.elem <T>(I) = static_cast <T>(Elem); });
2808+ }
2809+ }
2810+ Dst.initializeAllElements ();
2811+
2812+ return true ;
2813+ }
2814+
27812815bool InterpretBuiltin (InterpState &S, CodePtr OpPC, const CallExpr *Call,
27822816 uint32_t BuiltinID) {
27832817 if (!S.getASTContext ().BuiltinInfo .isConstantEvaluated (BuiltinID))
@@ -3210,9 +3244,36 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
32103244 case clang::X86::BI__builtin_ia32_pmuludq256:
32113245 case clang::X86::BI__builtin_ia32_pmuludq512:
32123246 return interp__builtin_ia32_pmul (S, OpPC, Call, BuiltinID);
3247+
32133248 case Builtin::BI__builtin_elementwise_fma:
32143249 return interp__builtin_elementwise_fma (S, OpPC, Call);
32153250
3251+ case X86::BI__builtin_ia32_selectb_128:
3252+ case X86::BI__builtin_ia32_selectb_256:
3253+ case X86::BI__builtin_ia32_selectb_512:
3254+ case X86::BI__builtin_ia32_selectw_128:
3255+ case X86::BI__builtin_ia32_selectw_256:
3256+ case X86::BI__builtin_ia32_selectw_512:
3257+ case X86::BI__builtin_ia32_selectd_128:
3258+ case X86::BI__builtin_ia32_selectd_256:
3259+ case X86::BI__builtin_ia32_selectd_512:
3260+ case X86::BI__builtin_ia32_selectq_128:
3261+ case X86::BI__builtin_ia32_selectq_256:
3262+ case X86::BI__builtin_ia32_selectq_512:
3263+ case X86::BI__builtin_ia32_selectph_128:
3264+ case X86::BI__builtin_ia32_selectph_256:
3265+ case X86::BI__builtin_ia32_selectph_512:
3266+ case X86::BI__builtin_ia32_selectpbf_128:
3267+ case X86::BI__builtin_ia32_selectpbf_256:
3268+ case X86::BI__builtin_ia32_selectpbf_512:
3269+ case X86::BI__builtin_ia32_selectps_128:
3270+ case X86::BI__builtin_ia32_selectps_256:
3271+ case X86::BI__builtin_ia32_selectps_512:
3272+ case X86::BI__builtin_ia32_selectpd_128:
3273+ case X86::BI__builtin_ia32_selectpd_256:
3274+ case X86::BI__builtin_ia32_selectpd_512:
3275+ return interp__builtin_select (S, OpPC, Call);
3276+
32163277 default :
32173278 S.FFDiag (S.Current ->getLocation (OpPC),
32183279 diag::note_invalid_subexpr_in_const_expr)
0 commit comments