[clang] [HLSL][SPIR-V] Add `-fspv-enable-maximal-reconvergence` flag to clang dxc. (PR #163474)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 14 16:29:43 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Lucie Choi (luciechoi)
<details>
<summary>Changes</summary>
Implement the frontend change to support maximal reconvergence feature.
The next work is to generate the corresponding SPIR-V instructions (`OpExtension` and `OpExecutionMode`) based on the llvm ir added in this CL `"enable-maximal-reconvergence"="true"`.
Addresses https://github.com/llvm/llvm-project/issues/136930
---
Full diff: https://github.com/llvm/llvm-project/pull/163474.diff
5 Files Affected:
- (modified) clang/include/clang/Basic/LangOptions.def (+1)
- (modified) clang/include/clang/Driver/Options.td (+9)
- (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+4)
- (modified) clang/lib/Driver/ToolChains/Clang.cpp (+2-1)
- (added) clang/test/CodeGenHLSL/vk-features/maximal_reconvergence.hlsl (+17)
``````````diff
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 9e850089ad87f..d32fecdb96f32 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -243,6 +243,7 @@ ENUM_LANGOPT(HLSLVersion, HLSLLangStd, 16, HLSL_Unset, NotCompatible, "HLSL Vers
LANGOPT(HLSLStrictAvailability, 1, 0, NotCompatible,
"Strict availability diagnostic mode for HLSL built-in functions.")
LANGOPT(HLSLSpvUseUnknownImageFormat, 1, 0, NotCompatible, "For storage images and texel buffers, sets the default format to 'Unknown' when not specified via the `vk::image_format` attribute. If this option is not used, the format is inferred from the resource's data type.")
+LANGOPT(HLSLSpvEnableMaximalReconvergence, 1, 0, NotCompatible, "Enables maximal reconvergence for SPIR-V codegen. This ensures that all control flow merges at the nearest possible merge point as defined by the Vulkan spec.")
LANGOPT(CUDAIsDevice , 1, 0, NotCompatible, "compiling for CUDA device")
LANGOPT(CUDAHostDeviceConstexpr, 1, 1, NotCompatible, "treating unattributed constexpr functions as __host__ __device__")
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 60c4ad408ee43..a6f7c6e12dddd 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -9573,6 +9573,15 @@ def fhlsl_spv_use_unknown_image_format
"from the resource's data type.">,
MarshallingInfoFlag<LangOpts<"HLSLSpvUseUnknownImageFormat">>;
+def fhlsl_spv_enable_maximal_reconvergence
+ : Flag<["-"], "fspv-enable-maximal-reconvergence">,
+ Group<dxc_Group>,
+ Visibility<[CC1Option, DXCOption]>,
+ HelpText<"Enables maximal reconvergence for SPIR-V codegen. This ensures "
+ "that all control flow merges at the nearest possible merge point "
+ "as defined by the Vulkan spec.">,
+ MarshallingInfoFlag<LangOpts<"HLSLSpvEnableMaximalReconvergence">>;
+
def no_wasm_opt : Flag<["--"], "no-wasm-opt">,
Group<m_Group>,
HelpText<"Disable the wasm-opt optimizer">,
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index ede1780592bf5..37c35a4768098 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -509,6 +509,10 @@ void clang::CodeGen::CGHLSLRuntime::setHLSLEntryAttributes(
if (CGM.getCodeGenOpts().OptimizationLevel == 0)
Fn->addFnAttr(llvm::Attribute::OptimizeNone);
Fn->addFnAttr(llvm::Attribute::NoInline);
+
+ if (CGM.getLangOpts().HLSLSpvEnableMaximalReconvergence) {
+ Fn->addFnAttr("enable-maximal-reconvergence", "true");
+ }
}
static Value *buildVectorInput(IRBuilder<> &B, Function *F, llvm::Type *Ty) {
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 107b9ffd439a3..1e794250d9d22 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3755,7 +3755,8 @@ static void RenderHLSLOptions(const ArgList &Args, ArgStringList &CmdArgs,
options::OPT_hlsl_entrypoint,
options::OPT_fdx_rootsignature_define,
options::OPT_fdx_rootsignature_version,
- options::OPT_fhlsl_spv_use_unknown_image_format};
+ options::OPT_fhlsl_spv_use_unknown_image_format,
+ options::OPT_fhlsl_spv_enable_maximal_reconvergence};
if (!types::isHLSL(InputType))
return;
for (const auto &Arg : ForwardedArguments)
diff --git a/clang/test/CodeGenHLSL/vk-features/maximal_reconvergence.hlsl b/clang/test/CodeGenHLSL/vk-features/maximal_reconvergence.hlsl
new file mode 100644
index 0000000000000..870fbabaac1bf
--- /dev/null
+++ b/clang/test/CodeGenHLSL/vk-features/maximal_reconvergence.hlsl
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple spirv1.6-unknown-vulkan1.3-compute -fspv-enable-maximal-reconvergence -emit-llvm -o - -O0 %s | FileCheck %s --check-prefixes=CHECK
+// RUN: %clang_cc1 -triple spirv1.6-unknown-vulkan1.3-compute -hlsl-entry test -fspv-enable-maximal-reconvergence -emit-llvm -o - -O0 %s | FileCheck %s --check-prefixes=CHECK-ENTRY
+
+[numthreads(1,1,1)]
+void main() {
+// CHECK: define void @main() [[attributeNumber:#[0-9]+]] {
+}
+
+// CHECK: attributes [[attributeNumber]] = {{.*}} "enable-maximal-reconvergence"="true" {{.*}}
+
+
+[numthreads(1,1,1)]
+void test() {
+// CHECK-ENTRY: define void @test() [[attributeNumber:#[0-9]+]] {
+}
+
+// CHECK-ENTRY: attributes [[attributeNumber]] = {{.*}} "enable-maximal-reconvergence"="true" {{.*}}
\ No newline at end of file
``````````
</details>
https://github.com/llvm/llvm-project/pull/163474
More information about the cfe-commits
mailing list