[llvm] [SPIRV] Support for SPV_INTEL_cluster_attributes extension (PR #131593)
via llvm-commits
llvm-commits at lists.llvm.org
Mon May 5 22:20:58 PDT 2025
https://github.com/EbinJose2002 updated https://github.com/llvm/llvm-project/pull/131593
>From 900be48e610e2b1b2ebf244eb5f9fd00e72bf0ee Mon Sep 17 00:00:00 2001
From: EbinJose2002 <ebin.jose at multicorewareinc.com>
Date: Mon, 17 Mar 2025 13:16:01 +0530
Subject: [PATCH 1/2] - Support for SPV_INTEL_cluster_attributes extension -
Added decorations for StallEnableINTEL and StallFreeINTEL
---
llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp | 4 +-
llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 68 +++++++++++++++++++
.../lib/Target/SPIRV/SPIRVSymbolicOperands.td | 4 ++
.../cluster_attributes.ll | 22 ++++++
4 files changed, 97 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_cluster_attributes/cluster_attributes.ll
diff --git a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
index 56cbd9414c9ee..528dd4d1dbdce 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
@@ -97,7 +97,9 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
SPIRV::Extension::Extension::
SPV_INTEL_subgroup_matrix_multiply_accumulate},
{"SPV_INTEL_ternary_bitwise_function",
- SPIRV::Extension::Extension::SPV_INTEL_ternary_bitwise_function}};
+ SPIRV::Extension::Extension::SPV_INTEL_ternary_bitwise_function},
+ {"SPV_INTEL_fpga_cluster_attributes",
+ SPIRV::Extension::Extension::SPV_INTEL_fpga_cluster_attributes}};
bool SPIRVExtensionsParser::parse(cl::Option &O, StringRef ArgName,
StringRef ArgValue,
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 6d2ecd563d200..cc697eccec60c 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -920,6 +920,10 @@ static void addOpDecorateReqs(const MachineInstr &MI, unsigned DecIndex,
} else if (Dec == SPIRV::Decoration::FPMaxErrorDecorationINTEL) {
Reqs.addRequirements(SPIRV::Capability::FPMaxErrorINTEL);
Reqs.addExtension(SPIRV::Extension::SPV_INTEL_fp_max_error);
+ } else if (Dec == SPIRV::Decoration::StallEnableINTEL) {
+ Reqs.addRequirements(SPIRV::Capability::FPGAClusterAttributesINTEL);
+ } else if (Dec == SPIRV::Decoration::StallFreeINTEL) {
+ Reqs.addRequirements(SPIRV::Capability::FPGAClusterAttributesV2INTEL);
}
}
@@ -1976,6 +1980,68 @@ static void handleMIFlagDecoration(MachineInstr &I, const SPIRVSubtarget &ST,
buildOpDecorate(DstReg, I, TII, SPIRV::Decoration::FPFastMathMode, {FMFlags});
}
+static std::vector<uint32_t>
+getMetaDataValues(std::vector<llvm::MDNode *> &MetaDataList) {
+ std::vector<uint32_t> res;
+ for (auto metaDataNode : MetaDataList) {
+ if (metaDataNode->getNumOperands() > 0) {
+ if (auto *CMD = llvm::dyn_cast<llvm::ConstantAsMetadata>(
+ metaDataNode->getOperand(0))) {
+ if (auto *CI = llvm::dyn_cast<llvm::ConstantInt>(CMD->getValue())) {
+ APInt val = CI->getValue();
+ int64_t decVal = val.getZExtValue();
+ res.push_back(decVal);
+ }
+ }
+ }
+ }
+ return res;
+}
+
+static void handleFunctionDecoration(llvm::Module::const_iterator F,
+ const SPIRVInstrInfo &TII,
+ MachineModuleInfo *MMI,
+ const SPIRVSubtarget &ST) {
+ MachineFunction *MF = MMI->getMachineFunction(*F);
+ Register FuncReg;
+ MachineInstr *FirstInstr = nullptr;
+ llvm::SmallVector<std::pair<unsigned int, llvm::MDNode *>> MetaDataList;
+ // Find function register and first instruction
+ for (auto &MBB : *MF) {
+ for (auto &MI : MBB) {
+ if (MI.getOpcode() == SPIRV::OpFunction) {
+ FirstInstr = &MI;
+ FuncReg = MI.getOperand(0).getReg();
+ break;
+ }
+ }
+ if (FuncReg.isValid() && FirstInstr)
+ break;
+ }
+ // Add function-level decorations based on metadata
+ F->getAllMetadata(MetaDataList);
+ for (auto &MetaData : MetaDataList) {
+ if (MetaData.second == F->getMetadata("stall_enable") ||
+ MetaData.second == F->getMetadata("stall_free")) {
+ if (ST.canUseExtension(
+ SPIRV::Extension::SPV_INTEL_fpga_cluster_attributes)) {
+ std::vector<llvm::MDNode *> MetaDataVector;
+ MetaDataVector.push_back(MetaData.second);
+ std::vector<uint32_t> params = getMetaDataValues(MetaDataVector);
+ if (params.at(0) == 1) {
+ if (MetaData.second == F->getMetadata("stall_enable")) {
+ buildOpDecorate(FuncReg, *FirstInstr, TII,
+ SPIRV::Decoration::StallEnableINTEL, {});
+ } else {
+ buildOpDecorate(FuncReg, *FirstInstr, TII,
+ SPIRV::Decoration::StallFreeINTEL, {});
+ }
+ }
+ }
+ }
+ }
+}
+
// Walk all functions and add decorations related to MI flags.
static void addDecorations(const Module &M, const SPIRVInstrInfo &TII,
MachineModuleInfo *MMI, const SPIRVSubtarget &ST,
@@ -1987,6 +2053,8 @@ static void addDecorations(const Module &M, const SPIRVInstrInfo &TII,
for (auto &MBB : *MF)
for (auto &MI : MBB)
handleMIFlagDecoration(MI, ST, TII, MAI.Reqs);
+
+ handleFunctionDecoration(F, TII, MMI, ST);
}
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
index cc32200a0a261..cd534385be80b 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
+++ b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
@@ -517,6 +517,8 @@ defm MemoryAccessAliasingINTEL : CapabilityOperand<5910, 0, 0, [SPV_INTEL_memory
defm FPMaxErrorINTEL : CapabilityOperand<6169, 0, 0, [SPV_INTEL_fp_max_error], []>;
defm TernaryBitwiseFunctionINTEL : CapabilityOperand<6241, 0, 0, [SPV_INTEL_ternary_bitwise_function], []>;
defm SubgroupMatrixMultiplyAccumulateINTEL : CapabilityOperand<6236, 0, 0, [SPV_INTEL_subgroup_matrix_multiply_accumulate], []>;
+defm FPGAClusterAttributesINTEL : CapabilityOperand<5904, 0, 0, [SPV_INTEL_fpga_cluster_attributes], []>;
+defm FPGAClusterAttributesV2INTEL : CapabilityOperand<6150, 0, 0, [SPV_INTEL_fpga_cluster_attributes], []>;
//===----------------------------------------------------------------------===//
// Multiclass used to define SourceLanguage enum values and at the same time
@@ -1268,6 +1270,8 @@ defm FunctionFloatingPointModeINTEL : DecorationOperand<6080, 0, 0, [], [Functio
defm AliasScopeINTEL : DecorationOperand<5914, 0, 0, [], [MemoryAccessAliasingINTEL]>;
defm NoAliasINTEL : DecorationOperand<5915, 0, 0, [], [MemoryAccessAliasingINTEL]>;
defm FPMaxErrorDecorationINTEL : DecorationOperand<6170, 0, 0, [], [FPMaxErrorINTEL]>;
+defm StallEnableINTEL : DecorationOperand<5905, 0, 0, [SPV_INTEL_fpga_cluster_attributes], [FPGAClusterAttributesINTEL]>;
+defm StallFreeINTEL : DecorationOperand<6151, 0, 0, [SPV_INTEL_fpga_cluster_attributes], [FPGAClusterAttributesV2INTEL]>;
//===----------------------------------------------------------------------===//
// Multiclass used to define BuiltIn enum values and at the same time
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_cluster_attributes/cluster_attributes.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_cluster_attributes/cluster_attributes.ll
new file mode 100644
index 0000000000000..bbc1949766118
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_cluster_attributes/cluster_attributes.ll
@@ -0,0 +1,22 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_fpga_cluster_attributes %s -o - | FileCheck %s
+
+; CHECK-DAG: OpCapability FPGAClusterAttributesINTEL
+; CHECK-DAG: OpCapability FPGAClusterAttributesV2INTEL
+; CHECK-DAG: OpExtension "SPV_INTEL_fpga_cluster_attributes"
+; CHECK-DAG: OpDecorate %[[#STALLENABLE_DEC:]] StallEnableINTEL
+; CHECK-DAG: OpDecorate %[[#STALLFREE_DEC:]] StallFreeINTEL
+; CHECK: %[[#STALLENABLE_DEC]] = OpFunction %[[#]] None %[[#]]
+; CHECK: %[[#STALLFREE_DEC]] = OpFunction %[[#]] None %[[#]]
+
+define spir_func void @test_fpga_stallenable_attr() !stall_enable !0 {
+ entry:
+ ret void
+}
+
+define spir_func void @test_fpga_stallfree_attr() !stall_free !1 {
+ entry:
+ ret void
+}
+
+!0 = !{ i32 1 }
+!1 = !{ i32 1 }
\ No newline at end of file
>From 628d3f8481a5c4fd6cc734b8f0e8e1d6b647a46f Mon Sep 17 00:00:00 2001
From: EbinJose2002 <ebin.jose at multicorewareinc.com>
Date: Tue, 6 May 2025 10:49:06 +0530
Subject: [PATCH 2/2] - Added documentation - Moved the function to
SPIRVUtils.cpp
---
llvm/docs/SPIRVUsage.rst | 2 +
llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 70 ++++++-------------
.../lib/Target/SPIRV/SPIRVSymbolicOperands.td | 4 +-
llvm/lib/Target/SPIRV/SPIRVUtils.cpp | 18 +++++
llvm/lib/Target/SPIRV/SPIRVUtils.h | 4 ++
5 files changed, 47 insertions(+), 51 deletions(-)
diff --git a/llvm/docs/SPIRVUsage.rst b/llvm/docs/SPIRVUsage.rst
index 6ff8034cac00c..114faaf36f941 100644
--- a/llvm/docs/SPIRVUsage.rst
+++ b/llvm/docs/SPIRVUsage.rst
@@ -213,6 +213,8 @@ list of supported SPIR-V extensions, sorted alphabetically by their extension na
- Adds a bitwise instruction on three operands and a look-up table index for specifying the bitwise operation to perform.
* - ``SPV_INTEL_subgroup_matrix_multiply_accumulate``
- Adds an instruction to compute the matrix product of an M x K matrix with a K x N matrix and then add an M x N matrix.
+ * - ``SPV_INTEL_cluster_attributes``
+ - Adds decorations to indicate the cluster attributes of a function.
To enable multiple extensions, list them separated by comma. For example, to enable support for atomic operations on floating-point numbers and arbitrary precision integers, use:
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index cc697eccec60c..67b1abca33961 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -1980,44 +1980,13 @@ static void handleMIFlagDecoration(MachineInstr &I, const SPIRVSubtarget &ST,
buildOpDecorate(DstReg, I, TII, SPIRV::Decoration::FPFastMathMode, {FMFlags});
}
-static std::vector<uint32_t>
-getMetaDataValues(std::vector<llvm::MDNode *> &MetaDataList) {
- std::vector<uint32_t> res;
- for (auto metaDataNode : MetaDataList) {
- if (metaDataNode->getNumOperands() > 0) {
- if (auto *CMD = llvm::dyn_cast<llvm::ConstantAsMetadata>(
- metaDataNode->getOperand(0))) {
- if (auto *CI = llvm::dyn_cast<llvm::ConstantInt>(CMD->getValue())) {
- APInt val = CI->getValue();
- int64_t decVal = val.getZExtValue();
- res.push_back(decVal);
- }
- }
- }
- }
- return res;
-}
-
-static void handleFunctionDecoration(llvm::Module::const_iterator F,
+static void handleFunctionDecoration(MachineInstr &MI, const SPIRVSubtarget &ST,
const SPIRVInstrInfo &TII,
- MachineModuleInfo *MMI,
- const SPIRVSubtarget &ST) {
- MachineFunction *MF = MMI->getMachineFunction(*F);
- Register FuncReg;
- MachineInstr *FirstInstr = nullptr;
+ SPIRV::ModuleAnalysisInfo &MAI,
+ llvm::Module::const_iterator F) {
+ Register FuncReg = MI.getOperand(0).getReg();
llvm::SmallVector<std::pair<unsigned int, llvm::MDNode *>> MetaDataList;
- // Find function register and first instruction
- for (auto &MBB : *MF) {
- for (auto &MI : MBB) {
- if (MI.getOpcode() == SPIRV::OpFunction) {
- FirstInstr = &MI;
- FuncReg = MI.getOperand(0).getReg();
- break;
- }
- }
- if (FuncReg.isValid() && FirstInstr)
- break;
- }
+
// Add function-level decorations based on metadata
F->getAllMetadata(MetaDataList);
for (auto &MetaData : MetaDataList) {
@@ -2025,17 +1994,18 @@ static void handleFunctionDecoration(llvm::Module::const_iterator F,
MetaData.second == F->getMetadata("stall_free")) {
if (ST.canUseExtension(
SPIRV::Extension::SPV_INTEL_fpga_cluster_attributes)) {
- std::vector<llvm::MDNode *> MetaDataVector;
+ llvm::SmallVector<llvm::MDNode *> MetaDataVector;
MetaDataVector.push_back(MetaData.second);
- std::vector<uint32_t> params = getMetaDataValues(MetaDataVector);
- if (params.at(0) == 1) {
- if (MetaData.second == F->getMetadata("stall_enable")) {
- buildOpDecorate(FuncReg, *FirstInstr, TII,
+ llvm::SmallVector<uint32_t> params =
+ getConstantFromMetadata(MetaDataVector);
+
+ if (params[0] == 1) {
+ if (MetaData.second == F->getMetadata("stall_enable"))
+ buildOpDecorate(FuncReg, MI, TII,
SPIRV::Decoration::StallEnableINTEL, {});
- } else {
- buildOpDecorate(FuncReg, *FirstInstr, TII,
- SPIRV::Decoration::StallFreeINTEL, {});
- }
+ else
+ buildOpDecorate(FuncReg, MI, TII, SPIRV::Decoration::StallFreeINTEL,
+ {});
}
}
}
@@ -2050,11 +2020,13 @@ static void addDecorations(const Module &M, const SPIRVInstrInfo &TII,
MachineFunction *MF = MMI->getMachineFunction(*F);
if (!MF)
continue;
- for (auto &MBB : *MF)
- for (auto &MI : MBB)
+ for (auto &MBB : *MF) {
+ for (auto &MI : MBB) {
handleMIFlagDecoration(MI, ST, TII, MAI.Reqs);
-
- handleFunctionDecoration(F, TII, MMI, ST);
+ if (MI.getOpcode() == SPIRV::OpFunction)
+ handleFunctionDecoration(MI, ST, TII, MAI, F);
+ }
+ }
}
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
index cd534385be80b..e0eec581434f3 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
+++ b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
@@ -518,7 +518,7 @@ defm FPMaxErrorINTEL : CapabilityOperand<6169, 0, 0, [SPV_INTEL_fp_max_error], [
defm TernaryBitwiseFunctionINTEL : CapabilityOperand<6241, 0, 0, [SPV_INTEL_ternary_bitwise_function], []>;
defm SubgroupMatrixMultiplyAccumulateINTEL : CapabilityOperand<6236, 0, 0, [SPV_INTEL_subgroup_matrix_multiply_accumulate], []>;
defm FPGAClusterAttributesINTEL : CapabilityOperand<5904, 0, 0, [SPV_INTEL_fpga_cluster_attributes], []>;
-defm FPGAClusterAttributesV2INTEL : CapabilityOperand<6150, 0, 0, [SPV_INTEL_fpga_cluster_attributes], []>;
+defm FPGAClusterAttributesV2INTEL : CapabilityOperand<6150, 0, 0, [SPV_INTEL_fpga_cluster_attributes], []>;
//===----------------------------------------------------------------------===//
// Multiclass used to define SourceLanguage enum values and at the same time
@@ -1271,7 +1271,7 @@ defm AliasScopeINTEL : DecorationOperand<5914, 0, 0, [], [MemoryAccessAliasingIN
defm NoAliasINTEL : DecorationOperand<5915, 0, 0, [], [MemoryAccessAliasingINTEL]>;
defm FPMaxErrorDecorationINTEL : DecorationOperand<6170, 0, 0, [], [FPMaxErrorINTEL]>;
defm StallEnableINTEL : DecorationOperand<5905, 0, 0, [SPV_INTEL_fpga_cluster_attributes], [FPGAClusterAttributesINTEL]>;
-defm StallFreeINTEL : DecorationOperand<6151, 0, 0, [SPV_INTEL_fpga_cluster_attributes], [FPGAClusterAttributesV2INTEL]>;
+defm StallFreeINTEL : DecorationOperand<6151, 0, 0, [SPV_INTEL_fpga_cluster_attributes], [FPGAClusterAttributesV2INTEL]>;
//===----------------------------------------------------------------------===//
// Multiclass used to define BuiltIn enum values and at the same time
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
index f38794afab436..2a4c5f3f9289e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
@@ -370,6 +370,24 @@ Type *getMDOperandAsType(const MDNode *N, unsigned I) {
return toTypedPointer(ElementTy);
}
+llvm::SmallVector<uint32_t>
+getConstantFromMetadata(llvm::SmallVector<llvm::MDNode *> &MetaDataList) {
+ llvm::SmallVector<uint32_t> res;
+ for (auto metaDataNode : MetaDataList) {
+ if (metaDataNode->getNumOperands() > 0) {
+ if (auto *CMD = llvm::dyn_cast<llvm::ConstantAsMetadata>(
+ metaDataNode->getOperand(0))) {
+ if (auto *CI = llvm::dyn_cast<llvm::ConstantInt>(CMD->getValue())) {
+ APInt val = CI->getValue();
+ int64_t decVal = val.getZExtValue();
+ res.push_back(decVal);
+ }
+ }
+ }
+ }
+ return res;
+}
+
// The set of names is borrowed from the SPIR-V translator.
// TODO: may be implemented in SPIRVBuiltins.td.
static bool isPipeOrAddressSpaceCastBI(const StringRef MangledName) {
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.h b/llvm/lib/Target/SPIRV/SPIRVUtils.h
index ccf394de45c89..a836bebd19995 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.h
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.h
@@ -243,6 +243,10 @@ bool isSpvIntrinsic(const Value *Arg);
// Get type of i-th operand of the metadata node.
Type *getMDOperandAsType(const MDNode *N, unsigned I);
+// Extract the constant value from the metadata node.
+llvm::SmallVector<uint32_t>
+getConstantFromMetadata(llvm::SmallVector<llvm::MDNode *> &MetaDataList);
+
// If OpenCL or SPIR-V builtin function name is recognized, return a demangled
// name, otherwise return an empty string.
std::string getOclOrSpirvBuiltinDemangledName(StringRef Name);
More information about the llvm-commits
mailing list