Skip to content

Commit a43c0cf

Browse files
authored
[SPIR-V] Generate SPIR-V instructions when 'enable-maximal-reconvergence' function attribute is set (llvm#163682)
Implement maximal reconvergence in SPIR-V codegen. Addresses llvm#136930
1 parent 1e7a23f commit a43c0cf

File tree

7 files changed

+77
-15
lines changed

7 files changed

+77
-15
lines changed

clang/lib/Driver/ToolChains/HLSL.cpp

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -191,23 +191,35 @@ void getSpirvExtOperand(StringRef SpvExtensionArg, raw_ostream &out) {
191191
// The extensions that are commented out are supported in DXC, but the SPIR-V
192192
// backend does not know about them yet.
193193
static const std::vector<StringRef> DxcSupportedExtensions = {
194-
"SPV_KHR_16bit_storage", "SPV_KHR_device_group",
195-
"SPV_KHR_fragment_shading_rate", "SPV_KHR_multiview",
196-
"SPV_KHR_post_depth_coverage", "SPV_KHR_non_semantic_info",
197-
"SPV_KHR_shader_draw_parameters", "SPV_KHR_ray_tracing",
198-
"SPV_KHR_shader_clock", "SPV_EXT_demote_to_helper_invocation",
199-
"SPV_EXT_descriptor_indexing", "SPV_EXT_fragment_fully_covered",
194+
"SPV_KHR_16bit_storage",
195+
"SPV_KHR_device_group",
196+
"SPV_KHR_fragment_shading_rate",
197+
"SPV_KHR_multiview",
198+
"SPV_KHR_post_depth_coverage",
199+
"SPV_KHR_non_semantic_info",
200+
"SPV_KHR_shader_draw_parameters",
201+
"SPV_KHR_ray_tracing",
202+
"SPV_KHR_shader_clock",
203+
"SPV_EXT_demote_to_helper_invocation",
204+
"SPV_EXT_descriptor_indexing",
205+
"SPV_EXT_fragment_fully_covered",
200206
"SPV_EXT_fragment_invocation_density",
201-
"SPV_EXT_fragment_shader_interlock", "SPV_EXT_mesh_shader",
202-
"SPV_EXT_shader_stencil_export", "SPV_EXT_shader_viewport_index_layer",
207+
"SPV_EXT_fragment_shader_interlock",
208+
"SPV_EXT_mesh_shader",
209+
"SPV_EXT_shader_stencil_export",
210+
"SPV_EXT_shader_viewport_index_layer",
203211
// "SPV_AMD_shader_early_and_late_fragment_tests",
204-
"SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type",
205-
"SPV_KHR_ray_query", "SPV_EXT_shader_image_int64",
206-
"SPV_KHR_fragment_shader_barycentric", "SPV_KHR_physical_storage_buffer",
212+
"SPV_GOOGLE_hlsl_functionality1",
213+
"SPV_GOOGLE_user_type",
214+
"SPV_KHR_ray_query",
215+
"SPV_EXT_shader_image_int64",
216+
"SPV_KHR_fragment_shader_barycentric",
217+
"SPV_KHR_physical_storage_buffer",
207218
"SPV_KHR_vulkan_memory_model",
208219
// "SPV_KHR_compute_shader_derivatives",
209-
// "SPV_KHR_maximal_reconvergence",
210-
"SPV_KHR_float_controls", "SPV_NV_shader_subgroup_partitioned",
220+
"SPV_KHR_maximal_reconvergence",
221+
"SPV_KHR_float_controls",
222+
"SPV_NV_shader_subgroup_partitioned",
211223
// "SPV_KHR_quad_control"
212224
};
213225

llvm/docs/SPIRVUsage.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ Below is a list of supported SPIR-V extensions, sorted alphabetically by their e
235235
- Adds execution modes and decorations to control floating-point computations in both kernels and shaders. It can be used on whole modules and individual instructions.
236236
* - ``SPV_INTEL_predicated_io``
237237
- Adds predicated load and store instructions that conditionally read from or write to memory based on a boolean predicate.
238+
* - ``SPV_KHR_maximal_reconvergence``
239+
- Adds execution mode and capability to enable maximal reconvergence.
238240

239241
SPIR-V representation in LLVM IR
240242
================================

llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class SPIRVAsmPrinter : public AsmPrinter {
7878
void outputExecutionModeFromNumthreadsAttribute(
7979
const MCRegister &Reg, const Attribute &Attr,
8080
SPIRV::ExecutionMode::ExecutionMode EM);
81+
void outputExecutionModeFromEnableMaximalReconvergenceAttr(
82+
const MCRegister &Reg, const SPIRVSubtarget &ST);
8183
void outputExecutionMode(const Module &M);
8284
void outputAnnotations(const Module &M);
8385
void outputModuleSections();
@@ -495,6 +497,20 @@ void SPIRVAsmPrinter::outputExecutionModeFromNumthreadsAttribute(
495497
outputMCInst(Inst);
496498
}
497499

500+
void SPIRVAsmPrinter::outputExecutionModeFromEnableMaximalReconvergenceAttr(
501+
const MCRegister &Reg, const SPIRVSubtarget &ST) {
502+
assert(ST.canUseExtension(SPIRV::Extension::SPV_KHR_maximal_reconvergence) &&
503+
"Function called when SPV_KHR_maximal_reconvergence is not enabled.");
504+
505+
MCInst Inst;
506+
Inst.setOpcode(SPIRV::OpExecutionMode);
507+
Inst.addOperand(MCOperand::createReg(Reg));
508+
unsigned EM =
509+
static_cast<unsigned>(SPIRV::ExecutionMode::MaximallyReconvergesKHR);
510+
Inst.addOperand(MCOperand::createImm(EM));
511+
outputMCInst(Inst);
512+
}
513+
498514
void SPIRVAsmPrinter::outputExecutionMode(const Module &M) {
499515
NamedMDNode *Node = M.getNamedMetadata("spirv.ExecutionMode");
500516
if (Node) {
@@ -551,6 +567,10 @@ void SPIRVAsmPrinter::outputExecutionMode(const Module &M) {
551567
if (Attribute Attr = F.getFnAttribute("hlsl.numthreads"); Attr.isValid())
552568
outputExecutionModeFromNumthreadsAttribute(
553569
FReg, Attr, SPIRV::ExecutionMode::LocalSize);
570+
if (Attribute Attr = F.getFnAttribute("enable-maximal-reconvergence");
571+
Attr.getValueAsBool()) {
572+
outputExecutionModeFromEnableMaximalReconvergenceAttr(FReg, *ST);
573+
}
554574
if (MDNode *Node = F.getMetadata("work_group_size_hint"))
555575
outputExecutionModeFromMDNode(FReg, Node,
556576
SPIRV::ExecutionMode::LocalSizeHint, 3, 1);

llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,9 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
153153
SPIRV::Extension::Extension::
154154
SPV_EXT_relaxed_printf_string_address_space},
155155
{"SPV_INTEL_predicated_io",
156-
SPIRV::Extension::Extension::SPV_INTEL_predicated_io}};
156+
SPIRV::Extension::Extension::SPV_INTEL_predicated_io},
157+
{"SPV_KHR_maximal_reconvergence",
158+
SPIRV::Extension::Extension::SPV_KHR_maximal_reconvergence}};
157159

158160
bool SPIRVExtensionsParser::parse(cl::Option &O, StringRef ArgName,
159161
StringRef ArgValue,

llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2155,6 +2155,9 @@ static void collectReqs(const Module &M, SPIRV::ModuleAnalysisInfo &MAI,
21552155
SPIRV::OperandCategory::ExecutionModeOperand,
21562156
SPIRV::ExecutionMode::LocalSize, ST);
21572157
}
2158+
if (F.getFnAttribute("enable-maximal-reconvergence").getValueAsBool()) {
2159+
MAI.Reqs.addExtension(SPIRV::Extension::SPV_KHR_maximal_reconvergence);
2160+
}
21582161
if (F.getMetadata("work_group_size_hint"))
21592162
MAI.Reqs.getAndAddRequirements(
21602163
SPIRV::OperandCategory::ExecutionModeOperand,

llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ defm SPV_KHR_float_controls2 : ExtensionOperand<124, [EnvVulkan, EnvOpenCL]>;
386386
defm SPV_INTEL_tensor_float32_conversion : ExtensionOperand<125, [EnvOpenCL]>;
387387
defm SPV_KHR_bfloat16 : ExtensionOperand<126, [EnvVulkan, EnvOpenCL]>;
388388
defm SPV_INTEL_predicated_io : ExtensionOperand<127, [EnvOpenCL]>;
389+
defm SPV_KHR_maximal_reconvergence : ExtensionOperand<128, [EnvVulkan]>;
389390

390391
//===----------------------------------------------------------------------===//
391392
// Multiclass used to define Capabilities enum values and at the same time
@@ -698,7 +699,7 @@ defm IntersectionNV: ExecutionModelOperand<5314, [RayTracingNV]>;
698699
defm AnyHitNV: ExecutionModelOperand<5315, [RayTracingNV]>;
699700
defm ClosestHitNV: ExecutionModelOperand<5316, [RayTracingNV]>;
700701
defm MissNV: ExecutionModelOperand<5317, [RayTracingNV]>;
701-
defm CallableNV: ExecutionModelOperand<5318, [RayTracingNV]>;
702+
defm CallableNV : ExecutionModelOperand<5318, [RayTracingNV]>;
702703

703704
//===----------------------------------------------------------------------===//
704705
// Multiclass used to define MemoryModel enum values and at the same time
@@ -805,6 +806,7 @@ defm RoundingModeRTNINTEL : ExecutionModeOperand<5621, [RoundToInfinityINTEL]>;
805806
defm FloatingPointModeALTINTEL : ExecutionModeOperand<5622, [FloatingPointModeINTEL]>;
806807
defm FloatingPointModeIEEEINTEL : ExecutionModeOperand<5623, [FloatingPointModeINTEL]>;
807808
defm FPFastMathDefault : ExecutionModeOperand<6028, [FloatControls2]>;
809+
defm MaximallyReconvergesKHR : ExecutionModeOperand<6023, [Shader]>;
808810

809811
//===----------------------------------------------------------------------===//
810812
// Multiclass used to define StorageClass enum values and at the same time
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv1.6-unknown-vulkan1.3-compute --spirv-ext=+SPV_KHR_maximal_reconvergence %s -o - | FileCheck %s
2+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.6-unknown-vulkan1.3-compute --spirv-ext=+SPV_KHR_maximal_reconvergence %s -o - -filetype=obj | spirv-val %}
3+
4+
; CHECK: OpCapability Shader
5+
; CHECK: OpExtension "SPV_KHR_maximal_reconvergence"
6+
; CHECK-NOT: OpExecutionMode {{.*}} MaximallyReconvergesKHR
7+
; CHECK: OpExecutionMode [[main:%[0-9]+]] MaximallyReconvergesKHR
8+
; CHECK-NOT: OpExecutionMode {{.*}} MaximallyReconvergesKHR
9+
; CHECK: OpName [[main]] "main"
10+
define void @main() local_unnamed_addr #0 {
11+
entry:
12+
ret void
13+
}
14+
15+
define void @negative() local_unnamed_addr #1 {
16+
entry:
17+
ret void
18+
}
19+
20+
attributes #0 = { "enable-maximal-reconvergence"="true" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
21+
attributes #1 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }

0 commit comments

Comments
 (0)