[llvm] [DirectX] Fix shader flag version-checking logic to match DXC (PR #136787)

Deric C. via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 22 16:39:27 PDT 2025


https://github.com/Icohedron created https://github.com/llvm/llvm-project/pull/136787

This PR primarily fixes the version-checking logic of the shader flags `ResMayNotAlias` and `Max64UAVs` to correctly match DXC's behavior.

Primary changes:

- The logic for determining the presence of UAVs for the `ResMayNotAlias` shader flag checked against the DXIL Version when it should have been checking against the DXIL Validator Version. (See DXC: [DxilShaderFlags.cpp#L484](https://github.com/microsoft/DirectXShaderCompiler/blob/f19b5da54170210e3cbc7f080be3f080abc52505/lib/DXIL/DxilShaderFlags.cpp#L484))

- The logic for counting UAVs for the `Max64UAVs` shader flag checked against the DXIL Version when it should have been checking against the DXIL Validator Version. (See DXC: [DxilModule.cpp#L327](https://github.com/microsoft/DirectXShaderCompiler/blob/f19b5da54170210e3cbc7f080be3f080abc52505/lib/DXIL/DxilModule.cpp#L327))

- Tests have been modified to test the corrected behaviors for these two flags

Additional changes included for consistency:

- The logic for setting `UseNativeLowPrecision` now checks against Shader Model version instead of DXIL version to be consistent with the code comments from DXC ([DxilShaderFlags.h#L280](https://github.com/microsoft/DirectXShaderCompiler/blob/f19b5da54170210e3cbc7f080be3f080abc52505/include/dxc/DXIL/DxilShaderFlags.h#L280)).

- An additional test has been added to ensure that the module flag "dx.nativelowprec" set to 0 does not apply the `UseNativeLowPrecision` shader flag

- Related shader flag tests were renamed to be more consistent, and some comments were edited for clarification


>From 220f62d9a3fd3c507afebc105b5975a7f753c79e Mon Sep 17 00:00:00 2001
From: Icohedron <cheung.deric at gmail.com>
Date: Tue, 22 Apr 2025 22:49:56 +0000
Subject: [PATCH] Fix version-checking logic of shader flags

---
 llvm/lib/Target/DirectX/DXILShaderFlags.cpp   | 17 +++++----
 ...m6_5.ll => max-64-uavs-array-valver1.5.ll} | 11 ++++--
 ...m6_6.ll => max-64-uavs-array-valver1.6.ll} |  9 ++++-
 .../DirectX/ShaderFlags/res-may-alias-0.ll    |  2 +
 ...model6.6.ll => res-may-not-alias-sm6.6.ll} |  2 +-
 ...model6.7.ll => res-may-not-alias-sm6.7.ll} |  2 +-
 ...l6.8.ll => res-may-not-alias-valver1.8.ll} | 11 ++++--
 .../ShaderFlags/use-native-low-precision-0.ll | 37 +++++++++++++++++++
 ...ision.ll => use-native-low-precision-1.ll} |  0
 9 files changed, 72 insertions(+), 19 deletions(-)
 rename llvm/test/CodeGen/DirectX/ShaderFlags/{max-64-uavs-array-sm6_5.ll => max-64-uavs-array-valver1.5.ll} (82%)
 rename llvm/test/CodeGen/DirectX/ShaderFlags/{max-64-uavs-array-sm6_6.ll => max-64-uavs-array-valver1.6.ll} (82%)
 rename llvm/test/CodeGen/DirectX/ShaderFlags/{res-may-not-alias-shadermodel6.6.ll => res-may-not-alias-sm6.6.ll} (99%)
 rename llvm/test/CodeGen/DirectX/ShaderFlags/{res-may-not-alias-shadermodel6.7.ll => res-may-not-alias-sm6.7.ll} (99%)
 rename llvm/test/CodeGen/DirectX/ShaderFlags/{res-may-not-alias-shadermodel6.8.ll => res-may-not-alias-valver1.8.ll} (82%)
 create mode 100644 llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-0.ll
 rename llvm/test/CodeGen/DirectX/ShaderFlags/{use-native-low-precision.ll => use-native-low-precision-1.ll} (100%)

diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
index 282b9dcf6de2b..10bee7256f4d6 100644
--- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
+++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
@@ -132,9 +132,10 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF,
     case Intrinsic::dx_resource_handlefrombinding: {
       dxil::ResourceTypeInfo &RTI = DRTM[cast<TargetExtType>(II->getType())];
 
-      // Set ResMayNotAlias if DXIL version >= 1.8 and function uses UAVs
+      // Set ResMayNotAlias if DXIL validator version >= 1.8 and the function
+      // uses UAVs
       if (!CSF.ResMayNotAlias && CanSetResMayNotAlias &&
-          MMDI.DXILVersion >= VersionTuple(1, 8) && RTI.isUAV())
+          MMDI.ValidatorVersion >= VersionTuple(1, 8) && RTI.isUAV())
         CSF.ResMayNotAlias = true;
 
       switch (RTI.getResourceKind()) {
@@ -208,15 +209,15 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
         continue;
       }
 
-      // Set ResMayNotAlias to true if DXIL version < 1.8 and there are UAVs
-      // present globally.
-      if (CanSetResMayNotAlias && MMDI.DXILVersion < VersionTuple(1, 8))
+      // Set ResMayNotAlias to true if DXIL validator version < 1.8 and there
+      // are UAVs present globally.
+      if (CanSetResMayNotAlias && MMDI.ValidatorVersion < VersionTuple(1, 8))
         SCCSF.ResMayNotAlias = !DRM.uavs().empty();
 
       // Set UseNativeLowPrecision using dx.nativelowprec module metadata
       if (auto *NativeLowPrec = mdconst::extract_or_null<ConstantInt>(
               M.getModuleFlag("dx.nativelowprec")))
-        if (MMDI.DXILVersion >= VersionTuple(1, 2) &&
+        if (MMDI.ShaderModelVersion >= VersionTuple(6, 2) &&
             NativeLowPrec->getValue() != 0)
           SCCSF.UseNativeLowPrecision = true;
 
@@ -259,9 +260,9 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
   // Set the Max64UAVs flag if the number of UAVs is > 8
   uint32_t NumUAVs = 0;
   for (auto &UAV : DRM.uavs())
-    if (MMDI.DXILVersion < VersionTuple(1, 6))
+    if (MMDI.ValidatorVersion < VersionTuple(1, 6))
       NumUAVs++;
-    else // MMDI.DXILVersion >= VersionTuple(1, 6)
+    else // MMDI.ValidatorVersion >= VersionTuple(1, 6)
       NumUAVs += UAV.getBinding().Size;
   if (NumUAVs > 8)
     CombinedSFMask.Max64UAVs = true;
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-sm6_5.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.5.ll
similarity index 82%
rename from llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-sm6_5.ll
rename to llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.5.ll
index 5b978d67866be..a157c124f9dfc 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-sm6_5.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.5.ll
@@ -1,13 +1,13 @@
 ; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
 
 ; This test makes sure that resource arrays only add 1 to the count of the
-; number of UAVs for setting the shader flag '64 UAV slots' when the shader
-; model version is < 6.6
+; number of UAVs for setting the shader flag '64 UAV slots' when the validator
+; version is < 1.6
 
 ; Note: there is no feature flag here (only a module flag), so we don't have an
 ; object test.
 
-target triple = "dxil-pc-shadermodel6.5-library"
+target triple = "dxil-pc-shadermodel6.7-library"
 
 ; CHECK:      Combined Shader Flags for Module
 ; CHECK-NEXT: Shader Flags Value: 0x00000000
@@ -29,5 +29,10 @@ define void @test() "hlsl.export" {
   ret void
 }
 
+; Set validator version to 1.5
+!dx.valver = !{!1}
+!1 = !{i32 1, i32 5}
+
+; Set this flag to 1 to prevent the ResMayNotAlias flag from being set
 !llvm.module.flags = !{!0}
 !0 = !{i32 1, !"dx.resmayalias", i32 1}
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-sm6_6.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.6.ll
similarity index 82%
rename from llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-sm6_6.ll
rename to llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.6.ll
index 4b901a78e6ea4..2b5f3edd47b12 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-sm6_6.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.6.ll
@@ -2,12 +2,12 @@
 
 ; This test makes sure that resource arrays sizes are accounted for when
 ; counting the number of UAVs for setting the shader flag '64 UAV slots' when
-; the shader model version is >= 6.6
+; the validator version is >= 1.6
 
 ; Note: there is no feature flag here (only a module flag), so we don't have an
 ; object test.
 
-target triple = "dxil-pc-shadermodel6.6-library"
+target triple = "dxil-pc-shadermodel6.7-library"
 
 ; CHECK:      Combined Shader Flags for Module
 ; CHECK-NEXT: Shader Flags Value: 0x00008000
@@ -29,5 +29,10 @@ define void @test() "hlsl.export" {
   ret void
 }
 
+; Set validator version to 1.6
+!dx.valver = !{!1}
+!1 = !{i32 1, i32 6}
+
+; Set this flag to 1 to prevent the ResMayNotAlias flag from being set
 !llvm.module.flags = !{!0}
 !0 = !{i32 1, !"dx.resmayalias", i32 1}
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-0.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-0.ll
index d15b5c7b61984..77d80470d6501 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-0.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-0.ll
@@ -35,9 +35,11 @@ define float @loadSRV() #0 {
 }
 
 !llvm.module.flags = !{!0}
+!dx.valver = !{!1}
 
 ; dx.resmayalias should never appear with a value of 0.
 ; But if it does, ensure that it has no effect.
 !0 = !{i32 1, !"dx.resmayalias", i32 0}
+!1 = !{i32 1, i32 8}
 
 attributes #0 = { convergent norecurse nounwind "hlsl.export"}
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.6.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.6.ll
similarity index 99%
rename from llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.6.ll
rename to llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.6.ll
index da7c4c619790c..e7828c6569912 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.6.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.6.ll
@@ -1,7 +1,7 @@
 ; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
 
 ; This test checks to ensure the behavior of the DXIL shader flag analysis
-; for the flag ResMayNotAlias is correct when the DXIL Version is 1.6. The
+; for the flag ResMayNotAlias is correct when the DXIL Version is < 1.7. The
 ; ResMayNotAlias flag (0x20000000) should not be set at all.
 
 target triple = "dxil-pc-shadermodel6.6-library"
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.7.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.7.ll
similarity index 99%
rename from llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.7.ll
rename to llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.7.ll
index 87a76162f734e..da75a3dfc7cd5 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.7.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.7.ll
@@ -1,7 +1,7 @@
 ; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
 
 ; This test checks to ensure the behavior of the DXIL shader flag analysis
-; for the flag ResMayNotAlias is correct when the DXIL Version is 1.7. The
+; for the flag ResMayNotAlias is correct when the DXIL Version is >= 1.7. The
 ; ResMayNotAlias flag (0x20000000) should be set on all functions if there are
 ; one or more UAVs present globally in the module.
 
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.8.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-valver1.8.ll
similarity index 82%
rename from llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.8.ll
rename to llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-valver1.8.ll
index a309d8ecea56c..a5be9f5bc69a9 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.8.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-valver1.8.ll
@@ -1,11 +1,11 @@
 ; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
 
-; This test checks to ensure the behavior of the DXIL shader flag analysis
-; for the flag ResMayNotAlias is correct when the DXIL Version is 1.8. The
-; ResMayNotAlias flag (0x20000000) should only be set when a function uses a
+; This test checks to ensure the behavior of the DXIL shader flag analysis for
+; the flag ResMayNotAlias is correct when the DXIL validator version is >= 1.8.
+; The ResMayNotAlias flag (0x20000000) should only be set when a function uses a
 ; UAV.
 
-target triple = "dxil-pc-shadermodel6.8-library"
+target triple = "dxil-pc-shadermodel6.7-library"
 
 ; CHECK:      Combined Shader Flags for Module
 ; CHECK-NEXT: Shader Flags Value: 0x200000010
@@ -35,4 +35,7 @@ define float @loadSRV() #0 {
   ret float %val
 }
 
+!dx.valver = !{!1}
+!1 = !{i32 1, i32 8}
+
 attributes #0 = { convergent norecurse nounwind "hlsl.export"}
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-0.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-0.ll
new file mode 100644
index 0000000000000..4c9040706189d
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-0.ll
@@ -0,0 +1,37 @@
+; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
+
+; Check that when the dx.nativelowprec module flag is set to 0, the module-level
+; shader flag UseNativeLowPrecision is not set
+
+target triple = "dxil-pc-shadermodel6.7-library"
+
+;CHECK: ; Combined Shader Flags for Module
+;CHECK-NEXT: ; Shader Flags Value: 0x00000020
+;CHECK-NEXT: ;
+;CHECK-NEXT: ; Note: shader requires additional functionality:
+;CHECK-NEXT: ; Note: extra DXIL module flags:
+;CHECK-NEXT: ;       D3D11_1_SB_GLOBAL_FLAG_ENABLE_MINIMUM_PRECISION
+;CHECK-NOT:  ;       Native 16bit types enabled
+;CHECK-NEXT: ;
+;CHECK-NEXT: ; Shader Flags for Module Functions
+
+;CHECK-LABEL: ; Function add_i16 : 0x00000020
+define i16 @add_i16(i16 %a, i16 %b) {
+  %sum = add i16 %a, %b
+  ret i16 %sum
+}
+
+;CHECK-LABEL: ; Function add_i32 : 0x00000000
+define i32 @add_i32(i32 %a, i32 %b) {
+  %sum = add i32 %a, %b
+  ret i32 %sum
+}
+
+;CHECK-LABEL: ; Function add_half : 0x00000020
+define half @add_half(half %a, half %b) {
+  %sum = fadd half %a, %b
+  ret half %sum
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"dx.nativelowprec", i32 0}
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll
similarity index 100%
rename from llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision.ll
rename to llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll



More information about the llvm-commits mailing list