[clang] [Clang] Add vector gather / scatter builtins to clang (PR #157895)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 15 10:38:59 PDT 2025
================
@@ -2361,6 +2363,101 @@ static ExprResult BuiltinMaskedStore(Sema &S, CallExpr *TheCall) {
return TheCall;
}
+static ExprResult BuiltinMaskedGather(Sema &S, CallExpr *TheCall) {
+ if (S.checkArgCountRange(TheCall, 3, 4))
+ return ExprError();
+
+ Expr *MaskArg = TheCall->getArg(0);
+ Expr *IdxArg = TheCall->getArg(1);
+ Expr *PtrArg = TheCall->getArg(2);
+ if (CheckMaskedBuiltinArgs(S, MaskArg, PtrArg, 3, /*Vector=*/false))
+ return ExprError();
+
+ QualType IdxTy = IdxArg->getType();
+ const VectorType *IdxVecTy = IdxTy->getAs<VectorType>();
+ if (!IdxTy->isExtVectorType() || !IdxVecTy->getElementType()->isIntegerType())
+ return S.Diag(MaskArg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+ << 1 << /* vector of */ 4 << /* integer */ 1 << /* no fp */ 0
+ << IdxTy;
+
+ QualType MaskTy = MaskArg->getType();
+ QualType PtrTy = PtrArg->getType();
+ QualType PointeeTy = PtrTy->getPointeeType();
+ const VectorType *MaskVecTy = MaskTy->getAs<VectorType>();
+ if (MaskVecTy->getNumElements() != IdxVecTy->getNumElements())
+ return ExprError(
+ S.Diag(TheCall->getBeginLoc(), diag::err_vec_masked_load_store_size)
+ << S.getASTContext().BuiltinInfo.getQuotedName(
+ TheCall->getBuiltinCallee())
+ << MaskTy << IdxTy);
+
+ QualType RetTy =
+ S.Context.getExtVectorType(PointeeTy, MaskVecTy->getNumElements());
+ if (TheCall->getNumArgs() == 4) {
+ Expr *PassThruArg = TheCall->getArg(3);
+ QualType PassThruTy = PassThruArg->getType();
+ if (!S.Context.hasSameType(PassThruTy, RetTy))
+ return S.Diag(PassThruArg->getExprLoc(),
+ diag::err_vec_masked_load_store_ptr)
+ << /* fourth argument */ 4 << RetTy;
+ }
+
+ TheCall->setType(RetTy);
+ return TheCall;
+}
+
+static ExprResult BuiltinMaskedScatter(Sema &S, CallExpr *TheCall) {
+ if (S.checkArgCount(TheCall, 4))
+ return ExprError();
+
+ Expr *MaskArg = TheCall->getArg(0);
+ Expr *IdxArg = TheCall->getArg(1);
+ Expr *ValArg = TheCall->getArg(2);
+ Expr *PtrArg = TheCall->getArg(3);
+
+ if (CheckMaskedBuiltinArgs(S, MaskArg, PtrArg, 3, /*Vector=*/false))
+ return ExprError();
+
+ QualType IdxTy = IdxArg->getType();
+ const VectorType *IdxVecTy = IdxTy->getAs<VectorType>();
+ if (!IdxTy->isExtVectorType() || !IdxVecTy->getElementType()->isIntegerType())
+ return S.Diag(MaskArg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+ << 2 << /* vector of */ 4 << /* integer */ 1 << /* no fp */ 0
+ << IdxTy;
+
+ QualType ValTy = ValArg->getType();
+ QualType MaskTy = MaskArg->getType();
+ QualType PtrTy = PtrArg->getType();
+ QualType PointeeTy = PtrTy->getPointeeType();
+
+ const VectorType *MaskVecTy = MaskTy->getAs<VectorType>();
+ const VectorType *ValVecTy = ValTy->getAs<VectorType>();
+ if (MaskVecTy->getNumElements() != IdxVecTy->getNumElements())
+ return ExprError(
+ S.Diag(TheCall->getBeginLoc(), diag::err_vec_masked_load_store_size)
+ << S.getASTContext().BuiltinInfo.getQuotedName(
+ TheCall->getBuiltinCallee())
+ << MaskTy << IdxTy);
+ if (MaskVecTy->getNumElements() != ValVecTy->getNumElements())
+ return ExprError(
+ S.Diag(TheCall->getBeginLoc(), diag::err_vec_masked_load_store_size)
+ << S.getASTContext().BuiltinInfo.getQuotedName(
+ TheCall->getBuiltinCallee())
+ << MaskTy << ValTy);
+
+ QualType ArgTy =
+ S.Context.getExtVectorType(PointeeTy, MaskVecTy->getNumElements());
+ if (!S.Context.hasSameType(ValTy, ArgTy))
+ return ExprError(S.Diag(TheCall->getBeginLoc(),
+ diag::err_vec_builtin_incompatible_vector)
+ << TheCall->getDirectCallee() << /*isMorethantwoArgs*/ 2
----------------
tbaederr wrote:
```suggestion
<< TheCall->getDirectCallee() << /*isMoreThanTwoArgs*/ 2
```
https://github.com/llvm/llvm-project/pull/157895
More information about the cfe-commits
mailing list