[llvm] [SPIR-V] Fix SPV_INTEL_optnone and add SPV_EXT_optnone SPIR-V extensions (PR #118402)
Vyacheslav Levytskyy via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 2 14:02:07 PST 2024
https://github.com/VyacheslavLevytskyy created https://github.com/llvm/llvm-project/pull/118402
This PR fixes implementation of SPV_INTEL_optnone so that it emits OptNoneINTEL Function Control flag, and add implementation of the SPV_EXT_optnone SPIR-V extension.
>From dcbc99ef5f27eeb02fa82b52dc2debcd7072894f Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Mon, 2 Dec 2024 13:56:17 -0800
Subject: [PATCH] fix SPV_INTEL_optnone and add SPV_EXT_optnone SPIR-V
extensions
---
llvm/docs/SPIRVUsage.rst | 10 ++++----
llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp | 20 ++++++++++++----
llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp | 1 +
llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 13 +++++++----
.../lib/Target/SPIRV/SPIRVSymbolicOperands.td | 3 +++
.../SPIRV/extensions/SPV_EXT_optnone.ll | 20 ++++++++++++++++
.../SPIRV/extensions/SPV_INTEL_optnone.ll | 23 ++++++++-----------
7 files changed, 62 insertions(+), 28 deletions(-)
create mode 100644 llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_optnone.ll
diff --git a/llvm/docs/SPIRVUsage.rst b/llvm/docs/SPIRVUsage.rst
index ffb04dca00fc5c..a270761671941e 100644
--- a/llvm/docs/SPIRVUsage.rst
+++ b/llvm/docs/SPIRVUsage.rst
@@ -141,16 +141,18 @@ list of supported SPIR-V extensions, sorted alphabetically by their extension na
* - Extension Name
- Description
+ * - ``SPV_EXT_arithmetic_fence``
+ - Adds an instruction that prevents fast-math optimizations between its argument and the expression that contains it.
+ * - ``SPV_EXT_demote_to_helper_invocation``
+ - Adds an instruction that demotes a fragment shader invocation to a helper invocation.
+ * - ``SPV_EXT_optnone``
+ - Adds OptNoneEXT value for Function Control mask that indicates a request to not optimize the function.
* - ``SPV_EXT_shader_atomic_float16_add``
- Extends the SPV_EXT_shader_atomic_float_add extension to support atomically adding to 16-bit floating-point numbers in memory.
* - ``SPV_EXT_shader_atomic_float_add``
- Adds atomic add instruction on floating-point numbers.
* - ``SPV_EXT_shader_atomic_float_min_max``
- Adds atomic min and max instruction on floating-point numbers.
- * - ``SPV_EXT_arithmetic_fence``
- - Adds an instruction that prevents fast-math optimizations between its argument and the expression that contains it.
- * - ``SPV_EXT_demote_to_helper_invocation``
- - Adds an instruction that demotes a fragment shader invocation to a helper invocation.
* - ``SPV_INTEL_arbitrary_precision_integers``
- Allows generating arbitrary width integer types.
* - ``SPV_INTEL_bfloat16_conversion``
diff --git a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
index 3fdaa6aa3257ea..e8e853c5c758a6 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
@@ -65,7 +65,8 @@ bool SPIRVCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
}
// Based on the LLVM function attributes, get a SPIR-V FunctionControl.
-static uint32_t getFunctionControl(const Function &F) {
+static uint32_t getFunctionControl(const Function &F,
+ const SPIRVSubtarget *ST) {
MemoryEffects MemEffects = F.getMemoryEffects();
uint32_t FuncControl = static_cast<uint32_t>(SPIRV::FunctionControl::None);
@@ -80,6 +81,11 @@ static uint32_t getFunctionControl(const Function &F) {
else if (MemEffects.onlyReadsMemory())
FuncControl |= static_cast<uint32_t>(SPIRV::FunctionControl::Const);
+ if (ST->canUseExtension(SPIRV::Extension::SPV_INTEL_optnone) ||
+ ST->canUseExtension(SPIRV::Extension::SPV_EXT_optnone))
+ if (F.hasFnAttribute(Attribute::OptimizeNone))
+ FuncControl |= static_cast<uint32_t>(SPIRV::FunctionControl::OptNoneEXT);
+
return FuncControl;
}
@@ -346,6 +352,12 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
buildOpDecorate(VRegs[i][0], MIRBuilder,
SPIRV::Decoration::FuncParamAttr, {Attr});
}
+ if (Arg.hasAttribute(Attribute::StructRet)) {
+ auto Attr =
+ static_cast<unsigned>(SPIRV::FunctionParameterAttribute::Sret);
+ buildOpDecorate(VRegs[i][0], MIRBuilder,
+ SPIRV::Decoration::FuncParamAttr, {Attr});
+ }
if (F.getCallingConv() == CallingConv::SPIR_KERNEL) {
std::vector<SPIRV::Decoration::Decoration> ArgTypeQualDecs =
@@ -397,7 +409,7 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
FTy = fixFunctionTypeIfPtrArgs(GR, F, FTy, RetTy, ArgTypeVRegs);
SPIRVType *FuncTy = GR->getOrCreateOpTypeFunctionWithArgs(
FTy, RetTy, ArgTypeVRegs, MIRBuilder);
- uint32_t FuncControl = getFunctionControl(F);
+ uint32_t FuncControl = getFunctionControl(F, ST);
// Add OpFunction instruction
MachineInstrBuilder MB = MIRBuilder.buildInstr(SPIRV::OpFunction)
@@ -427,10 +439,8 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
// Handle entry points and function linkage.
if (isEntryPoint(F)) {
- const auto &STI = MIRBuilder.getMF().getSubtarget<SPIRVSubtarget>();
- auto executionModel = getExecutionModel(STI, F);
auto MIB = MIRBuilder.buildInstr(SPIRV::OpEntryPoint)
- .addImm(static_cast<uint32_t>(executionModel))
+ .addImm(static_cast<uint32_t>(getExecutionModel(*ST, F)))
.addUse(FuncVReg);
addStringImm(F.getName(), MIB);
} else if (F.getLinkage() != GlobalValue::InternalLinkage &&
diff --git a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
index 186bccc481a8a3..1eefa757053e7d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
@@ -42,6 +42,7 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
{"SPV_INTEL_global_variable_host_access",
SPIRV::Extension::Extension::SPV_INTEL_global_variable_host_access},
{"SPV_INTEL_optnone", SPIRV::Extension::Extension::SPV_INTEL_optnone},
+ {"SPV_EXT_optnone", SPIRV::Extension::Extension::SPV_EXT_optnone},
{"SPV_INTEL_usm_storage_classes",
SPIRV::Extension::Extension::SPV_INTEL_usm_storage_classes},
{"SPV_INTEL_split_barrier",
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index d9f928eb906408..f4780002681270 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -1541,11 +1541,14 @@ static void collectReqs(const Module &M, SPIRV::ModuleAnalysisInfo &MAI,
SPIRV::OperandCategory::ExecutionModeOperand,
SPIRV::ExecutionMode::VecTypeHint, ST);
- if (F.hasOptNone() &&
- ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
- // Output OpCapability OptNoneINTEL.
- MAI.Reqs.addExtension(SPIRV::Extension::SPV_INTEL_optnone);
- MAI.Reqs.addCapability(SPIRV::Capability::OptNoneINTEL);
+ if (F.hasOptNone()) {
+ if (ST.canUseExtension(SPIRV::Extension::SPV_EXT_optnone)) {
+ MAI.Reqs.addExtension(SPIRV::Extension::SPV_EXT_optnone);
+ MAI.Reqs.addCapability(SPIRV::Capability::OptNoneEXT);
+ } else if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
+ MAI.Reqs.addExtension(SPIRV::Extension::SPV_INTEL_optnone);
+ MAI.Reqs.addCapability(SPIRV::Capability::OptNoneINTEL);
+ }
}
}
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
index b88f6f5766a053..e85ea3a8991888 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
+++ b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
@@ -304,6 +304,7 @@ defm SPV_INTEL_global_variable_host_access : ExtensionOperand<109>;
defm SPV_INTEL_global_variable_fpga_decorations : ExtensionOperand<110>;
defm SPV_KHR_cooperative_matrix : ExtensionOperand<111>;
defm SPV_EXT_arithmetic_fence : ExtensionOperand<112>;
+defm SPV_EXT_optnone : ExtensionOperand<113>;
//===----------------------------------------------------------------------===//
// Multiclass used to define Capabilities enum values and at the same time
@@ -463,6 +464,7 @@ defm PhysicalStorageBufferAddressesEXT : CapabilityOperand<5347, 0, 0, [], [Shad
defm CooperativeMatrixNV : CapabilityOperand<5357, 0, 0, [], [Shader]>;
defm ArbitraryPrecisionIntegersINTEL : CapabilityOperand<5844, 0, 0, [SPV_INTEL_arbitrary_precision_integers], [Int8, Int16]>;
defm OptNoneINTEL : CapabilityOperand<6094, 0, 0, [SPV_INTEL_optnone], []>;
+defm OptNoneEXT : CapabilityOperand<6094, 0, 0, [SPV_EXT_optnone], []>;
defm BitInstructions : CapabilityOperand<6025, 0, 0, [SPV_KHR_bit_instructions], []>;
defm ExpectAssumeKHR : CapabilityOperand<5629, 0, 0, [SPV_KHR_expect_assume], []>;
defm FunctionPointersINTEL : CapabilityOperand<5603, 0, 0, [SPV_INTEL_function_pointers], []>;
@@ -1433,6 +1435,7 @@ defm Inline : FunctionControlOperand<0x1>;
defm DontInline : FunctionControlOperand<0x2>;
defm Pure : FunctionControlOperand<0x4>;
defm Const : FunctionControlOperand<0x8>;
+defm OptNoneEXT : FunctionControlOperand<0x10000>;
//===----------------------------------------------------------------------===//
// Multiclass used to define MemorySemantics enum values and at the same time
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_optnone.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_optnone.ll
new file mode 100644
index 00000000000000..e21d99badea061
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_optnone.ll
@@ -0,0 +1,20 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=+SPV_EXT_optnone %s -o - | FileCheck %s --check-prefixes=CHECK-EXTENSION
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK-NO-EXTENSION
+
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_EXT_optnone %s -o - -filetype=obj | spirv-val %}
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-EXTENSION: OpCapability OptNoneEXT
+; CHECK-EXTENSION: OpExtension "SPV_EXT_optnone"
+; CHECK-NO-EXTENSION-NOT: OpCapability OptNoneINTEL
+; CHECK-NO-EXTENSION-NOT: OpCapability OptNoneEXT
+; CHECK-NO-EXTENSION-NOT: OpExtension "SPV_INTEL_optnone"
+; CHECK-NO-EXTENSION-NOT: OpExtension "SPV_EXT_optnone"
+
+define spir_func void @foo() #0 {
+; CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] DontInline|OptNoneEXT %[[#]]
+entry:
+ ret void
+}
+
+attributes #0 = { nounwind optnone noinline }
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_optnone.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_optnone.ll
index 1744ec96804019..9830b8b4cd2d8f 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_optnone.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_optnone.ll
@@ -1,25 +1,20 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
-; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=+SPV_INTEL_optnone %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-EXTENSION
-; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NO-EXTENSION
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=+SPV_INTEL_optnone %s -o - | FileCheck %s --check-prefixes=CHECK-EXTENSION
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK-NO-EXTENSION
-; CHECK-EXTENSION: OpCapability OptNoneINTEL
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_optnone %s -o - -filetype=obj | spirv-val %}
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-EXTENSION: OpCapability OptNoneEXT
; CHECK-EXTENSION: OpExtension "SPV_INTEL_optnone"
; CHECK-NO-EXTENSION-NOT: OpCapability OptNoneINTEL
+; CHECK-NO-EXTENSION-NOT: OpCapability OptNoneEXT
; CHECK-NO-EXTENSION-NOT: OpExtension "SPV_INTEL_optnone"
+; CHECK-NO-EXTENSION-NOT: OpExtension "SPV_EXT_optnone"
-; Function Attrs: nounwind optnone noinline
define spir_func void @_Z3foov() #0 {
-; CHECK-LABEL: _Z3foov
-; CHECK: %4 = OpFunction %2 DontInline %3
-; CHECK-NEXT: %5 = OpLabel
-; CHECK-NEXT: OpReturn
-; CHECK-NEXT: OpFunctionEnd
+; CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] DontInline|OptNoneEXT %[[#]]
entry:
ret void
}
attributes #0 = { nounwind optnone noinline }
-
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; CHECK-EXTENSION: {{.*}}
-; CHECK-NO-EXTENSION: {{.*}}
More information about the llvm-commits
mailing list