@@ -2266,6 +2266,85 @@ static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall) {
2266
2266
return false;
2267
2267
}
2268
2268
2269
+ static bool CheckMaskedBuiltinArgs(Sema &S, Expr *MaskArg, Expr *PtrArg,
2270
+ unsigned Pos) {
2271
+ QualType MaskTy = MaskArg->getType();
2272
+ if (!MaskTy->isExtVectorBoolType())
2273
+ return S.Diag(MaskArg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
2274
+ << 1 << /* vector of */ 4 << /* booleans */ 6 << /* no fp */ 0
2275
+ << MaskTy;
2276
+
2277
+ QualType PtrTy = PtrArg->getType();
2278
+ if (!PtrTy->isPointerType() || !PtrTy->getPointeeType()->isVectorType())
2279
+ return S.Diag(PtrArg->getExprLoc(), diag::err_vec_masked_load_store_ptr)
2280
+ << Pos << "pointer to vector";
2281
+ return false;
2282
+ }
2283
+
2284
+ static ExprResult BuiltinMaskedLoad(Sema &S, CallExpr *TheCall) {
2285
+ if (S.checkArgCount(TheCall, 2))
2286
+ return ExprError();
2287
+
2288
+ Expr *MaskArg = TheCall->getArg(0);
2289
+ Expr *PtrArg = TheCall->getArg(1);
2290
+ if (CheckMaskedBuiltinArgs(S, MaskArg, PtrArg, 2))
2291
+ return ExprError();
2292
+
2293
+ QualType MaskTy = MaskArg->getType();
2294
+ QualType PtrTy = PtrArg->getType();
2295
+ QualType PointeeTy = PtrTy->getPointeeType();
2296
+ const VectorType *MaskVecTy = MaskTy->getAs<VectorType>();
2297
+ const VectorType *DataVecTy = PointeeTy->getAs<VectorType>();
2298
+ if (MaskVecTy->getNumElements() != DataVecTy->getNumElements())
2299
+ return ExprError(
2300
+ S.Diag(TheCall->getBeginLoc(), diag::err_vec_masked_load_store_size)
2301
+ << "__builtin_masked_load" << MaskTy << PointeeTy);
2302
+
2303
+ TheCall->setType(PointeeTy);
2304
+ return TheCall;
2305
+ }
2306
+
2307
+ static ExprResult BuiltinMaskedStore(Sema &S, CallExpr *TheCall) {
2308
+ if (S.checkArgCount(TheCall, 3))
2309
+ return ExprError();
2310
+
2311
+ Expr *MaskArg = TheCall->getArg(0);
2312
+ Expr *ValArg = TheCall->getArg(1);
2313
+ Expr *PtrArg = TheCall->getArg(2);
2314
+
2315
+ if (CheckMaskedBuiltinArgs(S, MaskArg, PtrArg, 3))
2316
+ return ExprError();
2317
+
2318
+ QualType MaskTy = MaskArg->getType();
2319
+ QualType PtrTy = PtrArg->getType();
2320
+ QualType ValTy = ValArg->getType();
2321
+ if (!ValTy->isVectorType())
2322
+ return ExprError(
2323
+ S.Diag(ValArg->getExprLoc(), diag::err_vec_masked_load_store_ptr)
2324
+ << 2 << "vector");
2325
+
2326
+ QualType PointeeTy = PtrTy->getPointeeType();
2327
+ const VectorType *MaskVecTy = MaskTy->getAs<VectorType>();
2328
+ const VectorType *ValVecTy = ValTy->getAs<VectorType>();
2329
+ const VectorType *PtrVecTy = PointeeTy->getAs<VectorType>();
2330
+
2331
+ if (MaskVecTy->getNumElements() != ValVecTy->getNumElements() ||
2332
+ MaskVecTy->getNumElements() != PtrVecTy->getNumElements())
2333
+ return ExprError(
2334
+ S.Diag(TheCall->getBeginLoc(), diag::err_vec_masked_load_store_size)
2335
+ << "__builtin_masked_store" << MaskTy << PointeeTy);
2336
+
2337
+ if (!S.Context.hasSameType(ValTy, PointeeTy))
2338
+ return ExprError(S.Diag(TheCall->getBeginLoc(),
2339
+ diag::err_vec_builtin_incompatible_vector)
2340
+ << TheCall->getDirectCallee() << /*isMorethantwoArgs*/ 2
2341
+ << SourceRange(TheCall->getArg(1)->getBeginLoc(),
2342
+ TheCall->getArg(1)->getEndLoc()));
2343
+
2344
+ TheCall->setType(S.Context.VoidTy);
2345
+ return TheCall;
2346
+ }
2347
+
2269
2348
static ExprResult BuiltinInvoke(Sema &S, CallExpr *TheCall) {
2270
2349
SourceLocation Loc = TheCall->getBeginLoc();
2271
2350
MutableArrayRef Args(TheCall->getArgs(), TheCall->getNumArgs());
@@ -2518,6 +2597,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
2518
2597
return BuiltinShuffleVector(TheCall);
2519
2598
// TheCall will be freed by the smart pointer here, but that's fine, since
2520
2599
// BuiltinShuffleVector guts it, but then doesn't release it.
2600
+ case Builtin::BI__builtin_masked_load:
2601
+ return BuiltinMaskedLoad(*this, TheCall);
2602
+ case Builtin::BI__builtin_masked_store:
2603
+ return BuiltinMaskedStore(*this, TheCall);
2521
2604
case Builtin::BI__builtin_invoke:
2522
2605
return BuiltinInvoke(*this, TheCall);
2523
2606
case Builtin::BI__builtin_prefetch:
0 commit comments