[clang] [llvm] [Vectorize][OpenMP] Support header-provided declare simd math variants (PR #189523)
Alexey Bataev via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 20 07:45:26 PDT 2026
================
@@ -11919,29 +11211,196 @@ evaluateCDTSize(const FunctionDecl *FD,
return C.getTypeSize(CDT);
}
+/// Mangle the parameter part of the vector function name according to
+/// their OpenMP classification. The mangling function is defined in
+/// section 4.5 of the AAVFABI(2021Q1).
+static std::string mangleVectorParameters(ArrayRef<ParamAttrTy> ParamAttrs) {
+ SmallString<256> Buffer;
+ llvm::raw_svector_ostream Out(Buffer);
+ for (const auto &ParamAttr : ParamAttrs) {
+ switch (ParamAttr.Kind) {
+ case Linear:
+ Out << 'l';
+ break;
+ case LinearRef:
+ Out << 'R';
+ break;
+ case LinearUVal:
+ Out << 'U';
+ break;
+ case LinearVal:
+ Out << 'L';
+ break;
+ case Uniform:
+ Out << 'u';
+ break;
+ case Vector:
+ Out << 'v';
+ break;
+ }
+ if (ParamAttr.HasVarStride)
+ Out << "s" << ParamAttr.StrideOrArg;
+ else if (ParamAttr.Kind == Linear || ParamAttr.Kind == LinearRef ||
+ ParamAttr.Kind == LinearUVal || ParamAttr.Kind == LinearVal) {
+ // Don't print the step value if it is not present or if it is
+ // equal to 1.
+ if (ParamAttr.StrideOrArg < 0)
+ Out << 'n' << -ParamAttr.StrideOrArg;
+ else if (ParamAttr.StrideOrArg != 1)
+ Out << ParamAttr.StrideOrArg;
+ }
+
+ if (!!ParamAttr.Alignment)
+ Out << 'a' << ParamAttr.Alignment;
+ }
+
+ return std::string(Out.str());
+}
+
+static void
+emitX86DeclareSimdFunction(const FunctionDecl *FD, llvm::Function *Fn,
+ const llvm::APSInt &VLENVal,
+ ArrayRef<ParamAttrTy> ParamAttrs,
+ OMPDeclareSimdDeclAttr::BranchStateTy State) {
+ struct ISADataTy {
+ char ISA;
+ unsigned VecRegSize;
+ };
+ ISADataTy ISAData[] = {
+ {
+ 'b', 128
+ }, // SSE
+ {
+ 'c', 256
+ }, // AVX
+ {
+ 'd', 256
+ }, // AVX2
+ {
+ 'e', 512
+ }, // AVX512
+ };
+ llvm::SmallVector<char, 2> Masked;
+ switch (State) {
+ case OMPDeclareSimdDeclAttr::BS_Undefined:
+ Masked.push_back('N');
+ Masked.push_back('M');
+ break;
+ case OMPDeclareSimdDeclAttr::BS_Notinbranch:
+ Masked.push_back('N');
+ break;
+ case OMPDeclareSimdDeclAttr::BS_Inbranch:
+ Masked.push_back('M');
+ break;
+ }
+ for (char Mask : Masked) {
+ for (const ISADataTy &Data : ISAData) {
+ SmallString<256> Buffer;
+ llvm::raw_svector_ostream Out(Buffer);
+ Out << "_ZGV" << Data.ISA << Mask;
+ if (!VLENVal) {
+ unsigned NumElts = evaluateCDTSize(FD, ParamAttrs);
+ assert(NumElts && "Non-zero simdlen/cdtsize expected");
+ Out << llvm::APSInt::getUnsigned(Data.VecRegSize / NumElts);
+ } else {
+ Out << VLENVal;
+ }
+ Out << mangleVectorParameters(ParamAttrs);
+ Out << '_' << Fn->getName();
+ Fn->addFnAttr(Out.str());
+ }
+ }
+}
+
+static void emitDeclareSimdVariantMetadata(CodeGenModule &CGM,
+ llvm::Function *Fn) {
+ llvm::SmallVector<std::string, 8> VariantMappings;
+ for (llvm::Attribute Attr : Fn->getAttributes().getFnAttrs()) {
+ if (!Attr.isStringAttribute())
+ continue;
+
+ StringRef VariantName = Attr.getKindAsString();
+ if (!VariantName.starts_with("_ZGV"))
+ continue;
+
+ std::optional<llvm::VFInfo> Info =
+ llvm::VFABI::tryDemangleForVFABI(VariantName, Fn->getFunctionType());
+ if (!Info)
+ continue;
+
+ llvm::FunctionType *VectorTy =
+ llvm::VFABI::createFunctionType(*Info, Fn->getFunctionType());
+ llvm::Function *VecFn = llvm::cast<llvm::Function>(
+ Fn->getParent()->getOrInsertFunction(Info->VectorName, VectorTy)
+ .getCallee());
+ CGM.addCompilerUsedGlobal(VecFn);
+ VariantMappings.push_back(std::string(VariantName));
+ }
+
+ if (VariantMappings.empty())
+ return;
+
+ SmallString<256> Buffer;
+ llvm::raw_svector_ostream Out(Buffer);
+ for (const std::string &VariantName : VariantMappings)
+ Out << VariantName << ',';
+ Buffer.pop_back();
+
+ Fn->removeFnAttr(llvm::VFABI::MappingsAttrName);
+ Fn->addFnAttr(llvm::VFABI::MappingsAttrName, Buffer.str());
+}
+
+static bool shouldEmitDeclareSimdVariantMetadata(const FunctionDecl *FD,
+ const SourceManager &SM) {
+ if (!FD)
+ return false;
+
+ for (const FunctionDecl *Redecl : FD->redecls()) {
+ if (!Redecl->hasAttr<OMPDeclareSimdDeclAttr>())
+ continue;
----------------
alexey-bataev wrote:
Same pattern as before, worth adding helper function
https://github.com/llvm/llvm-project/pull/189523
More information about the cfe-commits
mailing list