Skip to content

Commit dcbc99e

Browse files
fix SPV_INTEL_optnone and add SPV_EXT_optnone SPIR-V extensions
1 parent b27d97b commit dcbc99e

File tree

7 files changed

+62
-28
lines changed

7 files changed

+62
-28
lines changed

llvm/docs/SPIRVUsage.rst

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,16 +141,18 @@ list of supported SPIR-V extensions, sorted alphabetically by their extension na
141141

142142
* - Extension Name
143143
- Description
144+
* - ``SPV_EXT_arithmetic_fence``
145+
- Adds an instruction that prevents fast-math optimizations between its argument and the expression that contains it.
146+
* - ``SPV_EXT_demote_to_helper_invocation``
147+
- Adds an instruction that demotes a fragment shader invocation to a helper invocation.
148+
* - ``SPV_EXT_optnone``
149+
- Adds OptNoneEXT value for Function Control mask that indicates a request to not optimize the function.
144150
* - ``SPV_EXT_shader_atomic_float16_add``
145151
- Extends the SPV_EXT_shader_atomic_float_add extension to support atomically adding to 16-bit floating-point numbers in memory.
146152
* - ``SPV_EXT_shader_atomic_float_add``
147153
- Adds atomic add instruction on floating-point numbers.
148154
* - ``SPV_EXT_shader_atomic_float_min_max``
149155
- Adds atomic min and max instruction on floating-point numbers.
150-
* - ``SPV_EXT_arithmetic_fence``
151-
- Adds an instruction that prevents fast-math optimizations between its argument and the expression that contains it.
152-
* - ``SPV_EXT_demote_to_helper_invocation``
153-
- Adds an instruction that demotes a fragment shader invocation to a helper invocation.
154156
* - ``SPV_INTEL_arbitrary_precision_integers``
155157
- Allows generating arbitrary width integer types.
156158
* - ``SPV_INTEL_bfloat16_conversion``

llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ bool SPIRVCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
6565
}
6666

6767
// Based on the LLVM function attributes, get a SPIR-V FunctionControl.
68-
static uint32_t getFunctionControl(const Function &F) {
68+
static uint32_t getFunctionControl(const Function &F,
69+
const SPIRVSubtarget *ST) {
6970
MemoryEffects MemEffects = F.getMemoryEffects();
7071

7172
uint32_t FuncControl = static_cast<uint32_t>(SPIRV::FunctionControl::None);
@@ -80,6 +81,11 @@ static uint32_t getFunctionControl(const Function &F) {
8081
else if (MemEffects.onlyReadsMemory())
8182
FuncControl |= static_cast<uint32_t>(SPIRV::FunctionControl::Const);
8283

84+
if (ST->canUseExtension(SPIRV::Extension::SPV_INTEL_optnone) ||
85+
ST->canUseExtension(SPIRV::Extension::SPV_EXT_optnone))
86+
if (F.hasFnAttribute(Attribute::OptimizeNone))
87+
FuncControl |= static_cast<uint32_t>(SPIRV::FunctionControl::OptNoneEXT);
88+
8389
return FuncControl;
8490
}
8591

@@ -346,6 +352,12 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
346352
buildOpDecorate(VRegs[i][0], MIRBuilder,
347353
SPIRV::Decoration::FuncParamAttr, {Attr});
348354
}
355+
if (Arg.hasAttribute(Attribute::StructRet)) {
356+
auto Attr =
357+
static_cast<unsigned>(SPIRV::FunctionParameterAttribute::Sret);
358+
buildOpDecorate(VRegs[i][0], MIRBuilder,
359+
SPIRV::Decoration::FuncParamAttr, {Attr});
360+
}
349361

350362
if (F.getCallingConv() == CallingConv::SPIR_KERNEL) {
351363
std::vector<SPIRV::Decoration::Decoration> ArgTypeQualDecs =
@@ -397,7 +409,7 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
397409
FTy = fixFunctionTypeIfPtrArgs(GR, F, FTy, RetTy, ArgTypeVRegs);
398410
SPIRVType *FuncTy = GR->getOrCreateOpTypeFunctionWithArgs(
399411
FTy, RetTy, ArgTypeVRegs, MIRBuilder);
400-
uint32_t FuncControl = getFunctionControl(F);
412+
uint32_t FuncControl = getFunctionControl(F, ST);
401413

402414
// Add OpFunction instruction
403415
MachineInstrBuilder MB = MIRBuilder.buildInstr(SPIRV::OpFunction)
@@ -427,10 +439,8 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
427439

428440
// Handle entry points and function linkage.
429441
if (isEntryPoint(F)) {
430-
const auto &STI = MIRBuilder.getMF().getSubtarget<SPIRVSubtarget>();
431-
auto executionModel = getExecutionModel(STI, F);
432442
auto MIB = MIRBuilder.buildInstr(SPIRV::OpEntryPoint)
433-
.addImm(static_cast<uint32_t>(executionModel))
443+
.addImm(static_cast<uint32_t>(getExecutionModel(*ST, F)))
434444
.addUse(FuncVReg);
435445
addStringImm(F.getName(), MIB);
436446
} else if (F.getLinkage() != GlobalValue::InternalLinkage &&

llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
4242
{"SPV_INTEL_global_variable_host_access",
4343
SPIRV::Extension::Extension::SPV_INTEL_global_variable_host_access},
4444
{"SPV_INTEL_optnone", SPIRV::Extension::Extension::SPV_INTEL_optnone},
45+
{"SPV_EXT_optnone", SPIRV::Extension::Extension::SPV_EXT_optnone},
4546
{"SPV_INTEL_usm_storage_classes",
4647
SPIRV::Extension::Extension::SPV_INTEL_usm_storage_classes},
4748
{"SPV_INTEL_split_barrier",

llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,11 +1541,14 @@ static void collectReqs(const Module &M, SPIRV::ModuleAnalysisInfo &MAI,
15411541
SPIRV::OperandCategory::ExecutionModeOperand,
15421542
SPIRV::ExecutionMode::VecTypeHint, ST);
15431543

1544-
if (F.hasOptNone() &&
1545-
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
1546-
// Output OpCapability OptNoneINTEL.
1547-
MAI.Reqs.addExtension(SPIRV::Extension::SPV_INTEL_optnone);
1548-
MAI.Reqs.addCapability(SPIRV::Capability::OptNoneINTEL);
1544+
if (F.hasOptNone()) {
1545+
if (ST.canUseExtension(SPIRV::Extension::SPV_EXT_optnone)) {
1546+
MAI.Reqs.addExtension(SPIRV::Extension::SPV_EXT_optnone);
1547+
MAI.Reqs.addCapability(SPIRV::Capability::OptNoneEXT);
1548+
} else if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
1549+
MAI.Reqs.addExtension(SPIRV::Extension::SPV_INTEL_optnone);
1550+
MAI.Reqs.addCapability(SPIRV::Capability::OptNoneINTEL);
1551+
}
15491552
}
15501553
}
15511554
}

llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ defm SPV_INTEL_global_variable_host_access : ExtensionOperand<109>;
304304
defm SPV_INTEL_global_variable_fpga_decorations : ExtensionOperand<110>;
305305
defm SPV_KHR_cooperative_matrix : ExtensionOperand<111>;
306306
defm SPV_EXT_arithmetic_fence : ExtensionOperand<112>;
307+
defm SPV_EXT_optnone : ExtensionOperand<113>;
307308

308309
//===----------------------------------------------------------------------===//
309310
// Multiclass used to define Capabilities enum values and at the same time
@@ -463,6 +464,7 @@ defm PhysicalStorageBufferAddressesEXT : CapabilityOperand<5347, 0, 0, [], [Shad
463464
defm CooperativeMatrixNV : CapabilityOperand<5357, 0, 0, [], [Shader]>;
464465
defm ArbitraryPrecisionIntegersINTEL : CapabilityOperand<5844, 0, 0, [SPV_INTEL_arbitrary_precision_integers], [Int8, Int16]>;
465466
defm OptNoneINTEL : CapabilityOperand<6094, 0, 0, [SPV_INTEL_optnone], []>;
467+
defm OptNoneEXT : CapabilityOperand<6094, 0, 0, [SPV_EXT_optnone], []>;
466468
defm BitInstructions : CapabilityOperand<6025, 0, 0, [SPV_KHR_bit_instructions], []>;
467469
defm ExpectAssumeKHR : CapabilityOperand<5629, 0, 0, [SPV_KHR_expect_assume], []>;
468470
defm FunctionPointersINTEL : CapabilityOperand<5603, 0, 0, [SPV_INTEL_function_pointers], []>;
@@ -1433,6 +1435,7 @@ defm Inline : FunctionControlOperand<0x1>;
14331435
defm DontInline : FunctionControlOperand<0x2>;
14341436
defm Pure : FunctionControlOperand<0x4>;
14351437
defm Const : FunctionControlOperand<0x8>;
1438+
defm OptNoneEXT : FunctionControlOperand<0x10000>;
14361439

14371440
//===----------------------------------------------------------------------===//
14381441
// Multiclass used to define MemorySemantics enum values and at the same time
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=+SPV_EXT_optnone %s -o - | FileCheck %s --check-prefixes=CHECK-EXTENSION
2+
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK-NO-EXTENSION
3+
4+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_EXT_optnone %s -o - -filetype=obj | spirv-val %}
5+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
6+
7+
; CHECK-EXTENSION: OpCapability OptNoneEXT
8+
; CHECK-EXTENSION: OpExtension "SPV_EXT_optnone"
9+
; CHECK-NO-EXTENSION-NOT: OpCapability OptNoneINTEL
10+
; CHECK-NO-EXTENSION-NOT: OpCapability OptNoneEXT
11+
; CHECK-NO-EXTENSION-NOT: OpExtension "SPV_INTEL_optnone"
12+
; CHECK-NO-EXTENSION-NOT: OpExtension "SPV_EXT_optnone"
13+
14+
define spir_func void @foo() #0 {
15+
; CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] DontInline|OptNoneEXT %[[#]]
16+
entry:
17+
ret void
18+
}
19+
20+
attributes #0 = { nounwind optnone noinline }
Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,20 @@
1-
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
2-
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=+SPV_INTEL_optnone %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-EXTENSION
3-
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NO-EXTENSION
1+
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=+SPV_INTEL_optnone %s -o - | FileCheck %s --check-prefixes=CHECK-EXTENSION
2+
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK-NO-EXTENSION
43

5-
; CHECK-EXTENSION: OpCapability OptNoneINTEL
4+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_optnone %s -o - -filetype=obj | spirv-val %}
5+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
6+
7+
; CHECK-EXTENSION: OpCapability OptNoneEXT
68
; CHECK-EXTENSION: OpExtension "SPV_INTEL_optnone"
79
; CHECK-NO-EXTENSION-NOT: OpCapability OptNoneINTEL
10+
; CHECK-NO-EXTENSION-NOT: OpCapability OptNoneEXT
811
; CHECK-NO-EXTENSION-NOT: OpExtension "SPV_INTEL_optnone"
12+
; CHECK-NO-EXTENSION-NOT: OpExtension "SPV_EXT_optnone"
913

10-
; Function Attrs: nounwind optnone noinline
1114
define spir_func void @_Z3foov() #0 {
12-
; CHECK-LABEL: _Z3foov
13-
; CHECK: %4 = OpFunction %2 DontInline %3
14-
; CHECK-NEXT: %5 = OpLabel
15-
; CHECK-NEXT: OpReturn
16-
; CHECK-NEXT: OpFunctionEnd
15+
; CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] DontInline|OptNoneEXT %[[#]]
1716
entry:
1817
ret void
1918
}
2019

2120
attributes #0 = { nounwind optnone noinline }
22-
23-
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
24-
; CHECK-EXTENSION: {{.*}}
25-
; CHECK-NO-EXTENSION: {{.*}}

0 commit comments

Comments
 (0)