@@ -205,14 +205,19 @@ static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC,
205
205
206
206
if (A.isDummy () || B.isDummy ())
207
207
return false ;
208
+ if (!A.isBlockPointer () || !B.isBlockPointer ())
209
+ return false ;
208
210
209
211
bool IsWide = ID == Builtin::BIwcscmp || ID == Builtin::BIwcsncmp ||
210
212
ID == Builtin::BI__builtin_wcscmp ||
211
213
ID == Builtin::BI__builtin_wcsncmp;
212
214
assert (A.getFieldDesc ()->isPrimitiveArray ());
213
215
assert (B.getFieldDesc ()->isPrimitiveArray ());
214
216
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
+
216
221
PrimType ElemT = *S.getContext ().classify (getElemType (A));
217
222
218
223
auto returnResult = [&](int V) -> bool {
@@ -2778,6 +2783,40 @@ static bool interp__builtin_elementwise_fma(InterpState &S, CodePtr OpPC,
2778
2783
return true ;
2779
2784
}
2780
2785
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
+
2781
2820
bool InterpretBuiltin (InterpState &S, CodePtr OpPC, const CallExpr *Call,
2782
2821
uint32_t BuiltinID) {
2783
2822
if (!S.getASTContext ().BuiltinInfo .isConstantEvaluated (BuiltinID))
@@ -3210,9 +3249,36 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
3210
3249
case clang::X86::BI__builtin_ia32_pmuludq256:
3211
3250
case clang::X86::BI__builtin_ia32_pmuludq512:
3212
3251
return interp__builtin_ia32_pmul (S, OpPC, Call, BuiltinID);
3252
+
3213
3253
case Builtin::BI__builtin_elementwise_fma:
3214
3254
return interp__builtin_elementwise_fma (S, OpPC, Call);
3215
3255
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
+
3216
3282
default :
3217
3283
S.FFDiag (S.Current ->getLocation (OpPC),
3218
3284
diag::note_invalid_subexpr_in_const_expr)
0 commit comments