[clang] [llvm] [mlir] declare simd lowering backup (PR #185333)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Mar 8 17:57:54 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen
Author: Chi-Chun, Chen (chichunchen)
<details>
<summary>Changes</summary>
---
Patch is 41.72 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/185333.diff
7 Files Affected:
- (modified) clang/lib/CodeGen/CGOpenMPRuntime.cpp (+35-141)
- (modified) llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h (+86)
- (modified) llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp (+155)
- (modified) mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp (+25-28)
- (modified) mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp (+173)
- (added) mlir/test/Target/LLVMIR/openmp-declare-simd-aarch64.mlir (+19)
- (added) mlir/test/Target/LLVMIR/openmp-declare-simd-x86.mlir (+213)
``````````diff
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 09cc8c25538e2..c0727194a4607 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -11828,27 +11828,8 @@ void CGOpenMPRuntime::emitTargetDataStandAloneCall(
}
}
-namespace {
- /// Kind of parameter in a function with 'declare simd' directive.
-enum ParamKindTy {
- Linear,
- LinearRef,
- LinearUVal,
- LinearVal,
- Uniform,
- Vector,
-};
-/// Attribute set of the parameter.
-struct ParamAttrTy {
- ParamKindTy Kind = Vector;
- llvm::APSInt StrideOrArg;
- llvm::APSInt Alignment;
- bool HasVarStride = false;
-};
-} // namespace
-
static unsigned evaluateCDTSize(const FunctionDecl *FD,
- ArrayRef<ParamAttrTy> ParamAttrs) {
+ ArrayRef<llvm::DeclareSimdAttrTy> ParamAttrs) {
// Every vector variant of a SIMD-enabled function has a vector length (VLEN).
// If OpenMP clause "simdlen" is used, the VLEN is the value of the argument
// of that clause. The VLEN value must be power of 2.
@@ -11878,13 +11859,13 @@ static unsigned evaluateCDTSize(const FunctionDecl *FD,
} else {
unsigned Offset = 0;
if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
- if (ParamAttrs[Offset].Kind == Vector)
+ if (ParamAttrs[Offset].Kind == llvm::DeclareSimdKindTy::Vector)
CDT = C.getPointerType(C.getCanonicalTagType(MD->getParent()));
++Offset;
}
if (CDT.isNull()) {
for (unsigned I = 0, E = FD->getNumParams(); I < E; ++I) {
- if (ParamAttrs[I + Offset].Kind == Vector) {
+ if (ParamAttrs[I + Offset].Kind == llvm::DeclareSimdKindTy::Vector) {
CDT = FD->getParamDecl(I)->getType();
break;
}
@@ -11899,107 +11880,6 @@ static unsigned 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());
- }
- }
-}
-
// This are the Functions that are needed to mangle the name of the
// vector functions generated by the compiler, according to the rules
// defined in the "Vector Function ABI specifications for AArch64",
@@ -12007,19 +11887,21 @@ emitX86DeclareSimdFunction(const FunctionDecl *FD, llvm::Function *Fn,
// https://developer.arm.com/products/software-development-tools/hpc/arm-compiler-for-hpc/vector-function-abi.
/// Maps To Vector (MTV), as defined in 4.1.1 of the AAVFABI (2021Q1).
-static bool getAArch64MTV(QualType QT, ParamKindTy Kind) {
+static bool getAArch64MTV(QualType QT, llvm::DeclareSimdKindTy Kind) {
QT = QT.getCanonicalType();
if (QT->isVoidType())
return false;
- if (Kind == ParamKindTy::Uniform)
+ if (Kind == llvm::DeclareSimdKindTy::Uniform)
return false;
- if (Kind == ParamKindTy::LinearUVal || Kind == ParamKindTy::LinearRef)
+ if (Kind == llvm::DeclareSimdKindTy::LinearUVal ||
+ Kind == llvm::DeclareSimdKindTy::LinearRef)
return false;
- if ((Kind == ParamKindTy::Linear || Kind == ParamKindTy::LinearVal) &&
+ if ((Kind == llvm::DeclareSimdKindTy::Linear ||
+ Kind == llvm::DeclareSimdKindTy::LinearVal) &&
!QT->isReferenceType())
return false;
@@ -12052,7 +11934,8 @@ static bool getAArch64PBV(QualType QT, ASTContext &C) {
/// Computes the lane size (LS) of a return type or of an input parameter,
/// as defined by `LS(P)` in 3.2.1 of the AAVFABI.
/// TODO: Add support for references, section 3.2.1, item 1.
-static unsigned getAArch64LS(QualType QT, ParamKindTy Kind, ASTContext &C) {
+static unsigned getAArch64LS(QualType QT, llvm::DeclareSimdKindTy Kind,
+ ASTContext &C) {
if (!getAArch64MTV(QT, Kind) && QT.getCanonicalType()->isPointerType()) {
QualType PTy = QT.getCanonicalType()->getPointeeType();
if (getAArch64PBV(PTy, C))
@@ -12068,7 +11951,8 @@ static unsigned getAArch64LS(QualType QT, ParamKindTy Kind, ASTContext &C) {
// signature of the scalar function, as defined in 3.2.2 of the
// AAVFABI.
static std::tuple<unsigned, unsigned, bool>
-getNDSWDS(const FunctionDecl *FD, ArrayRef<ParamAttrTy> ParamAttrs) {
+getNDSWDS(const FunctionDecl *FD,
+ ArrayRef<llvm::DeclareSimdAttrTy> ParamAttrs) {
QualType RetType = FD->getReturnType().getCanonicalType();
ASTContext &C = FD->getASTContext();
@@ -12077,7 +11961,7 @@ getNDSWDS(const FunctionDecl *FD, ArrayRef<ParamAttrTy> ParamAttrs) {
llvm::SmallVector<unsigned, 8> Sizes;
if (!RetType->isVoidType()) {
- Sizes.push_back(getAArch64LS(RetType, ParamKindTy::Vector, C));
+ Sizes.push_back(getAArch64LS(RetType, llvm::DeclareSimdKindTy::Vector, C));
if (!getAArch64PBV(RetType, C) && getAArch64MTV(RetType, {}))
OutputBecomesInput = true;
}
@@ -12156,7 +12040,7 @@ static void addAArch64AdvSIMDNDSNames(unsigned NDS, StringRef Mask,
/// Emit vector function attributes for AArch64, as defined in the AAVFABI.
static void emitAArch64DeclareSimdFunction(
CodeGenModule &CGM, const FunctionDecl *FD, unsigned UserVLEN,
- ArrayRef<ParamAttrTy> ParamAttrs,
+ ArrayRef<llvm::DeclareSimdAttrTy> ParamAttrs,
OMPDeclareSimdDeclAttr::BranchStateTy State, StringRef MangledName,
char ISA, unsigned VecRegSize, llvm::Function *Fn, SourceLocation SLoc) {
@@ -12189,8 +12073,10 @@ static void emitAArch64DeclareSimdFunction(
}
}
+ llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
+
// Sort out parameter sequence.
- const std::string ParSeq = mangleVectorParameters(ParamAttrs);
+ const std::string ParSeq = OMPBuilder.mangleVectorParameters(ParamAttrs);
StringRef Prefix = "_ZGV";
// Generate simdlen from user input (if any).
if (UserVLEN) {
@@ -12266,7 +12152,8 @@ void CGOpenMPRuntime::emitDeclareSimdFunction(const FunctionDecl *FD,
++ParamPos;
}
for (const auto *Attr : FD->specific_attrs<OMPDeclareSimdDeclAttr>()) {
- llvm::SmallVector<ParamAttrTy, 8> ParamAttrs(ParamPositions.size());
+ llvm::SmallVector<llvm::DeclareSimdAttrTy, 8> ParamAttrs(
+ ParamPositions.size());
// Mark uniform parameters.
for (const Expr *E : Attr->uniforms()) {
E = E->IgnoreParenImpCasts();
@@ -12280,7 +12167,7 @@ void CGOpenMPRuntime::emitDeclareSimdFunction(const FunctionDecl *FD,
assert(It != ParamPositions.end() && "Function parameter not found");
Pos = It->second;
}
- ParamAttrs[Pos].Kind = Uniform;
+ ParamAttrs[Pos].Kind = llvm::DeclareSimdKindTy::Uniform;
}
// Get alignment info.
auto *NI = Attr->alignments_begin();
@@ -12341,15 +12228,15 @@ void CGOpenMPRuntime::emitDeclareSimdFunction(const FunctionDecl *FD,
.getQuantity();
}
}
- ParamAttrTy &ParamAttr = ParamAttrs[Pos];
+ llvm::DeclareSimdAttrTy &ParamAttr = ParamAttrs[Pos];
if (*MI == OMPC_LINEAR_ref)
- ParamAttr.Kind = LinearRef;
+ ParamAttr.Kind = llvm::DeclareSimdKindTy::LinearRef;
else if (*MI == OMPC_LINEAR_uval)
- ParamAttr.Kind = LinearUVal;
+ ParamAttr.Kind = llvm::DeclareSimdKindTy::LinearUVal;
else if (IsReferenceType)
- ParamAttr.Kind = LinearVal;
+ ParamAttr.Kind = llvm::DeclareSimdKindTy::LinearVal;
else
- ParamAttr.Kind = Linear;
+ ParamAttr.Kind = llvm::DeclareSimdKindTy::Linear;
// Assuming a stride of 1, for `linear` without modifiers.
ParamAttr.StrideOrArg = llvm::APSInt::getUnsigned(1);
if (*SI) {
@@ -12374,7 +12261,8 @@ void CGOpenMPRuntime::emitDeclareSimdFunction(const FunctionDecl *FD,
// rescale the value of linear_step with the byte size of the
// pointee type.
if (!ParamAttr.HasVarStride &&
- (ParamAttr.Kind == Linear || ParamAttr.Kind == LinearRef))
+ (ParamAttr.Kind == llvm::DeclareSimdKindTy::Linear ||
+ ParamAttr.Kind == llvm::DeclareSimdKindTy::LinearRef))
ParamAttr.StrideOrArg = ParamAttr.StrideOrArg * PtrRescalingFactor;
++SI;
++MI;
@@ -12387,8 +12275,14 @@ void CGOpenMPRuntime::emitDeclareSimdFunction(const FunctionDecl *FD,
ExprLoc = VLENExpr->getExprLoc();
}
OMPDeclareSimdDeclAttr::BranchStateTy State = Attr->getBranchState();
+ llvm::OpenMPIRBuilder &OMPBuilder =
+ CGM.getOpenMPRuntime().getOMPBuilder();
if (CGM.getTriple().isX86()) {
- emitX86DeclareSimdFunction(FD, Fn, VLENVal, ParamAttrs, State);
+ unsigned NumElts = evaluateCDTSize(FD, ParamAttrs);
+ assert(NumElts && "Non-zero simdlen/cdtsize expected");
+ OMPBuilder.emitX86DeclareSimdFunction(
+ Fn, NumElts, VLENVal, ParamAttrs,
+ static_cast<llvm::DeclareSimdBranch>(State));
} else if (CGM.getTriple().getArch() == llvm::Triple::aarch64) {
unsigned VLEN = VLENVal.getExtValue();
StringRef MangledName = Fn->getName();
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
index 9885ffc8b2065..266e19058998d 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
+++ b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
@@ -14,6 +14,7 @@
#ifndef LLVM_FRONTEND_OPENMP_OMPIRBUILDER_H
#define LLVM_FRONTEND_OPENMP_OMPIRBUILDER_H
+#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Frontend/Atomic/Atomic.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
@@ -498,6 +499,31 @@ class OffloadEntriesInfoManager {
OffloadEntriesDeviceGlobalVarTy OffloadEntriesDeviceGlobalVar;
};
+/// Kind of parameter in a function with 'declare simd' directive.
+enum class DeclareSimdKindTy {
+ Linear,
+ LinearRef,
+ LinearUVal,
+ LinearVal,
+ Uniform,
+ Vector,
+};
+
+/// Attribute set of the `declare simd` parameter.
+struct DeclareSimdAttrTy {
+ DeclareSimdKindTy Kind = DeclareSimdKindTy::Vector;
+ llvm::APSInt StrideOrArg;
+ llvm::APSInt Alignment;
+ bool HasVarStride = false;
+};
+
+/// Type of branch clause of the `declare simd` directive.
+enum class DeclareSimdBranch {
+ Undefined,
+ Inbranch,
+ Notinbranch,
+};
+
/// An interface to create LLVM-IR for OpenMP directives.
///
/// Each OpenMP directive has a corresponding public generator method.
@@ -1484,6 +1510,66 @@ class OpenMPIRBuilder {
Value *IfCond, omp::OrderKind Order,
ConstantInt *Simdlen, ConstantInt *Safelen);
+ /// Mangle the parameter portion of a vector function name according to the
+ /// OpenMP declare simd rules.
+ ///
+ /// The mangling follows the Vector Function ABI (AAVFABI) specification and
+ /// encodes, for each function parameter, its OpenMP classification
+ /// (vector, uniform, linear, etc.), optional linear step information, and
+ /// optional alignment.
+ ///
+ /// This helper produces only the parameter-encoding suffix; the caller is
+ /// responsible for adding ISA, masking, VLEN, and the base function name.
+ ///
+ /// \param ParamAttrs A list of per-parameter attributes describing how each
+ /// argument participates in SIMD execution.
+ ///
+ /// \returns A string encoding the parameter attributes suitable for inclusion
+ /// in a vector function name.
+ LLVM_ABI std::string
+ mangleVectorParameters(llvm::ArrayRef<DeclareSimdAttrTy> ParamAttrs);
+
+ /// Emit x86-specific vector function attributes for an OpenMP `declare simd`
+ /// directive.
+ ///
+ /// This function attaches one or more mangled vector-function-name attributes
+ /// to the given LLVM function, following the x86 Vector Function ABI.
+ ///
+ /// Depending on the branch clause, masked and/or unmasked variants are
+ /// emitted. The vector length is either taken from the explicit `simdlen`
+ /// clause or derived from the characteristic data type (CDT).
+ ///
+ /// \param Fn The LLVM function corresponding to the scalar version.
+ /// \param NumElements The number of SIMD lanes derived from the target ISA.
+ /// \param VLENVal Optional explicit SIMD length from the `simdlen`
+ /// clause.
+ /// \param ParamAttrs Per-parameter SIMD attributes (uniform, linear, etc.).
+ /// \param Branch The branch behavior specified by the `inbranch` or
+ /// `notinbranch` clause.
+ LLVM_ABI void emitX86DeclareSimdFunction(
+ llvm::Function *Fn, unsigned NumElements, const llvm::APSInt &VLENVal,
+ llvm::ArrayRef<DeclareSimdAttrTy> ParamAttrs, DeclareSimdBranch Branch);
+
+ /// Emit vector function attributes for an OpenMP `declare simd` directive.
+ ///
+ /// This is the target-independent entry point used by frontends and IR
+ /// translation layers. It dispatches to a target-specific implementation
+ /// based on the module target triple.
+ ///
+ /// If the target does not support `declare simd` lowering, this function
+ /// reports an error and performs no emission.
+ ///
+ /// \param Fn The LLVM function corresponding to the scalar version.
+ /// \param VLENVal Optional explicit SIMD length from the `simdlen`
+ /// clause.
+ /// \param ParamAttrs Per-parameter SIMD attributes (uniform, linear, etc.).
+ /// \param Branch The branch behavior specified by the `inbranch` or
+ /// `notinbranch` clause.
+ LLVM_ABI void
+ emitDeclareSimdFunction(llvm::Function *Fn, const llvm::APSInt &VLENVal,
+ llvm::ArrayRef<DeclareSimdAttrTy> ParamAttrs,
+ llvm::DeclareSimdBranch Branch);
+
/// Generator for '#omp flush'
///
/// \param Loc The location where the flush directive was encountered
diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index 1d522e9b14c7a..b96e991a999a4 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -6956,6 +6956,161 @@ void OpenMPIRBuilder::applySimd(CanonicalLoopInfo *CanonicalLoop,
addLoopMetadata(CanonicalLoop, LoopMDList);
}
+/// Return type size in bits for `Ty` using DL.
+/// If scalable, return known-min as a conservative approximation.
+static unsigned getTypeSizeInBits(llvm::Type *Ty, const llvm::DataLayout &DL) {
+ if (!Ty)
+ return 0;
+ llvm::TypeSize TS = DL.getTypeSizeInBits(Ty);
+
+ if (TS.isScalable())
+ return (unsigned)TS.getKnownMinValue();
+ return (unsigned)TS.getFixedValue();
+}
+
+/// Returns size in *bits* of the Characteristic Data Type (CDT).
+static unsigned evaluateCDTSize(const llvm::Function *Fn,
+ llvm::ArrayRef<DeclareSimdAttrTy> ParamAttrs) {
+ const llvm::DataLayout &DL = Fn->getParent()->getDataLayout();
+
+ llvm::Type *RetTy = Fn->getReturnType();
+ llvm::Type *CDT = nullptr;
+
+ // Non-void return => CDT = return type
+ if (RetTy && !RetTy->isVoidTy()) {
+ CDT = RetTy;
+ } else {
+ // First "Vector" param (ParamAttrs aligned with function params)
+ // If ParamAttrs is shorter than the parameter list, treat missing as Vector
+ // (matches the idea "default Kind is Vector").
+ unsigned NumParams = Fn->getFunctionType()->getNumParams();
+ for (unsigned I = 0; I < NumParams; ++I) {
+ bool IsVector = (I < ParamAttrs.size())
+ ? ParamAttrs[I].Kind == DeclareSimdKindTy::Vector
+ : true;
+ if (!IsVector)
+ continue;
+ CDT = Fn->getFunctionType()->getParamType(I);
+ break;
+ }
+ }
+
+ llvm::Type *IntTy = llvm::Type::getInt32Ty(Fn->getContext());
+ if (!CDT || CDT->isStructTy() || CDT->isArrayTy())
+ CDT = IntTy;
+
+ return getTypeSizeInBits(CDT, DL);
+}
+
+/// 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).
+std::string OpenMPIRBuilder::mangleVectorParameters(
+ llvm::ArrayRef<DeclareSimdAttrTy> ParamAttrs) {
+ llvm::SmallString<256> Buffer;
+ llvm::raw_svector_ostream Out(Buffer);
+ for (const auto &ParamAttr : ParamAttrs) {
+ switch (ParamAttr.Kind) {
+ case llvm::DeclareSimdKindTy::Linear:
+ Out << 'l';
+ break;
+ case llvm::DeclareSimdKindTy::LinearRef:
+ Out << 'R';
+ break;
+ case llvm::DeclareSimdKindTy::LinearUVal:
+ Out << 'U';
+ break;
+ case llvm::DeclareSimdKindTy::LinearVal:
+ Out << 'L';
+ break;
+ case llvm::DeclareSimdKindTy::Uniform:
+ Out << 'u';
+ break;
+ case llvm::DeclareSimdKindTy::Vector:
+ Out << 'v';
+ break;
+ }
+ if (ParamAttr.HasVarStride)
+ Out << "s" << ParamAttr.StrideOrArg;
+ else if (ParamAttr.Kind == llvm::DeclareSimdKindTy::Linear ||
+ ParamAttr.Kind == llvm::DeclareSimdKindTy::LinearRef ||
+ ParamAttr.Kind == llvm::DeclareSimdKindTy::LinearUVal ||
+ ParamAttr.Kind == llvm::DeclareSimdKindTy::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());
+}
+
+void OpenMPIRBuilder::emitX86DeclareSimdFunction(
+ llvm::Function *Fn, unsigned NumElts, const llvm::APSInt &VLENVal,
+ llvm::ArrayRef<DeclareSimdAttrTy> ParamAttrs, DeclareSimdBranch Branch) {
+ struct ISA...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/185333
More information about the llvm-commits
mailing list