[llvm] e33b7a1 - [DirectX] Implement Shader Flag Analysis for `UAVsAtEveryStage` (#137085)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 29 11:56:25 PDT 2025
Author: Deric C.
Date: 2025-04-29T11:56:21-07:00
New Revision: e33b7a1d6388007183b7657958a0d32626caea46
URL: https://github.com/llvm/llvm-project/commit/e33b7a1d6388007183b7657958a0d32626caea46
DIFF: https://github.com/llvm/llvm-project/commit/e33b7a1d6388007183b7657958a0d32626caea46.diff
LOG: [DirectX] Implement Shader Flag Analysis for `UAVsAtEveryStage` (#137085)
Fixes #112272
In addition to the implementation of the UAVsAtEveryStage shader flag
analysis, several unrelated tests have had the `dx.valver` module
metadata defined to avoid setting the UAVsAtEveryStage shader flag in
them.
Example:
```
!dx.valver = !{!0}
!0 = !{i32 1, i32 8}
```
---------
Co-authored-by: Justin Bogner <mail at justinbogner.com>
Added:
llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-lib-valver1.7.ll
llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-lib-valver1.8.ll
llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-vs.ll
Modified:
llvm/lib/Target/DirectX/DXILShaderFlags.cpp
llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.5.ll
llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.6.ll
llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs.ll
llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-1.ll
llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.6.ll
llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.7.ll
llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-valver1.8.ll
llvm/test/CodeGen/DirectX/ShaderFlags/typed-uav-load-additional-formats.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
index 036e8993c3959..b50a9b5d6051c 100644
--- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
+++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
@@ -32,6 +32,35 @@
using namespace llvm;
using namespace llvm::dxil;
+static bool hasUAVsAtEveryStage(DXILResourceMap &DRM,
+ const ModuleMetadataInfo &MMDI) {
+ if (DRM.uavs().empty())
+ return false;
+
+ switch (MMDI.ShaderProfile) {
+ default:
+ return false;
+ case Triple::EnvironmentType::Compute:
+ case Triple::EnvironmentType::Pixel:
+ return false;
+ case Triple::EnvironmentType::Vertex:
+ case Triple::EnvironmentType::Geometry:
+ case Triple::EnvironmentType::Hull:
+ case Triple::EnvironmentType::Domain:
+ return true;
+ case Triple::EnvironmentType::Library:
+ case Triple::EnvironmentType::RayGeneration:
+ case Triple::EnvironmentType::Intersection:
+ case Triple::EnvironmentType::AnyHit:
+ case Triple::EnvironmentType::ClosestHit:
+ case Triple::EnvironmentType::Miss:
+ case Triple::EnvironmentType::Callable:
+ case Triple::EnvironmentType::Mesh:
+ case Triple::EnvironmentType::Amplification:
+ return MMDI.ValidatorVersion < VersionTuple(1, 8);
+ }
+}
+
static bool checkWaveOps(Intrinsic::ID IID) {
// Currently unsupported intrinsics
// case Intrinsic::dx_wave_getlanecount:
@@ -266,6 +295,8 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
NumUAVs += UAV.getBinding().Size;
if (NumUAVs > 8)
CombinedSFMask.Max64UAVs = true;
+
+ CombinedSFMask.UAVsAtEveryStage = hasUAVsAtEveryStage(DRM, MMDI);
}
void ComputedShaderFlags::print(raw_ostream &OS) const {
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.5.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.5.ll
index b7e9aee2f5e95..af6001be1f610 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.5.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.5.ll
@@ -7,9 +7,10 @@
target triple = "dxil-pc-shadermodel6.7-library"
; CHECK: Combined Shader Flags for Module
-; CHECK-NEXT: Shader Flags Value: 0x00000000
+; CHECK-NEXT: Shader Flags Value: 0x00010000
-; CHECK-NOT: Note: shader requires additional functionality:
+; CHECK: Note: shader requires additional functionality:
+; CHECK: UAVs at every shader stage
; CHECK-NOT: 64 UAV slots
; CHECK: Function test : 0x00000000
@@ -26,10 +27,8 @@ 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-valver1.6.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.6.ll
index 46b105589620a..7e1d73b31b35b 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.6.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.6.ll
@@ -8,9 +8,10 @@
target triple = "dxil-pc-shadermodel6.7-library"
; CHECK: Combined Shader Flags for Module
-; CHECK-NEXT: Shader Flags Value: 0x00008000
+; CHECK-NEXT: Shader Flags Value: 0x00018000
; CHECK: Note: shader requires additional functionality:
+; CHECK: UAVs at every shader stage
; CHECK: 64 UAV slots
; CHECK: Function test : 0x00000000
@@ -27,19 +28,15 @@ 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}
; DXC: - Name: SFI0
; DXC-NEXT: Size: 8
; DXC-NEXT: Flags:
-; DXC-NOT: {{[A-Za-z]+: +true}}
-; DXC: Max64UAVs: true
-; DXC-NOT: {{[A-Za-z]+: +true}}
+; DXC: Max64UAVs: true
; DXC: NextUnusedBit: false
; DXC: ...
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs.ll
index 98bf6e41407de..a97fe5d45d00a 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs.ll
@@ -55,13 +55,13 @@ define void @test() "hlsl.export" {
}
!llvm.module.flags = !{!0}
+!dx.valver = !{!1}
!0 = !{i32 1, !"dx.resmayalias", i32 1}
+!1 = !{i32 1, i32 8}
; DXC: - Name: SFI0
; DXC-NEXT: Size: 8
; DXC-NEXT: Flags:
-; DXC-NOT: {{[A-Za-z]+: +true}}
-; DXC: Max64UAVs: true
-; DXC-NOT: {{[A-Za-z]+: +true}}
+; DXC: Max64UAVs: true
; DXC: NextUnusedBit: false
; DXC: ...
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-1.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-1.ll
index 4c75c7886e776..8884b3d681cbe 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-1.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-1.ll
@@ -35,7 +35,9 @@ define float @loadSRV() #0 {
}
!llvm.module.flags = !{!0}
-
!0 = !{i32 1, !"dx.resmayalias", i32 1}
+!dx.valver = !{!1}
+!1 = !{i32 1, i32 8}
+
attributes #0 = { convergent norecurse nounwind "hlsl.export"}
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.6.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.6.ll
index 9dba2b7f98c3b..fe0a801209eba 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.6.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.6.ll
@@ -34,4 +34,7 @@ define float @loadSRV() #0 {
ret float %val
}
+!dx.valver = !{!0}
+!0 = !{i32 1, i32 8}
+
attributes #0 = { convergent norecurse nounwind "hlsl.export"}
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.7.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.7.ll
index ce4b4d499da72..934319557a11f 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.7.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.7.ll
@@ -1,14 +1,18 @@
; 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
-; ResMayNotAlias flag (0x20000000) should be set on all functions if there are
-; one or more UAVs present globally in the module.
+; for the flag ResMayNotAlias is correct when the DXIL Version is >= 1.7 and the
+; DXIL Validator Version < 1.8. The ResMayNotAlias flag (0x20000000) should be
+; set on all functions if there are one or more UAVs present globally in the
+; module.
target triple = "dxil-pc-shadermodel6.7-library"
; CHECK: Combined Shader Flags for Module
-; CHECK-NEXT: Shader Flags Value: 0x200000010
+; CHECK-NEXT: Shader Flags Value: 0x200010010
+
+; CHECK: Note: shader requires additional functionality:
+; CHECK: UAVs at every shader stage
; CHECK: Note: extra DXIL module flags:
; CHECK: Raw and structured buffers
@@ -35,4 +39,7 @@ define float @loadSRV() #0 {
ret float %val
}
+!dx.valver = !{!0}
+!0 = !{i32 1, i32 7}
+
attributes #0 = { convergent norecurse nounwind "hlsl.export"}
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-valver1.8.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-valver1.8.ll
index 4ba74a1a9ff28..142c0a7cb3f48 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-valver1.8.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-valver1.8.ll
@@ -35,7 +35,7 @@ define float @loadSRV() #0 {
ret float %val
}
-!dx.valver = !{!1}
-!1 = !{i32 1, i32 8}
+!dx.valver = !{!0}
+!0 = !{i32 1, i32 8}
attributes #0 = { convergent norecurse nounwind "hlsl.export"}
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/typed-uav-load-additional-formats.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/typed-uav-load-additional-formats.ll
index 1bb8a4d78eb16..e9fed4ccbb37c 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/typed-uav-load-additional-formats.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/typed-uav-load-additional-formats.ll
@@ -44,7 +44,9 @@ define void @noload(<4 x float> %val) #0 {
}
!llvm.module.flags = !{!0}
+!dx.valver = !{!1}
!0 = !{i32 1, !"dx.resmayalias", i32 1}
+!1 = !{i32 1, i32 8}
attributes #0 = { convergent norecurse nounwind "hlsl.export"}
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-lib-valver1.7.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-lib-valver1.7.ll
new file mode 100644
index 0000000000000..552f513095fa5
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-lib-valver1.7.ll
@@ -0,0 +1,35 @@
+; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
+; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
+
+; This test ensures that a library shader with a UAV gets the module and
+; shader feature flag UAVsAtEveryStage when the DXIL validator version is < 1.8
+
+target triple = "dxil-pc-shadermodel6.5-library"
+
+; CHECK: Combined Shader Flags for Module
+; CHECK-NEXT: Shader Flags Value: 0x00010000
+
+; CHECK: Note: shader requires additional functionality:
+; CHECK: UAVs at every shader stage
+
+; CHECK: Function test : 0x00000000
+define void @test() "hlsl.export" {
+ ; RWBuffer<float> Buf : register(u0, space0)
+ %buf0 = call target("dx.TypedBuffer", float, 1, 0, 1)
+ @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0t(
+ i32 0, i32 0, i32 1, i32 0, i1 false)
+ ret void
+}
+
+!dx.valver = !{!1}
+!1 = !{i32 1, i32 7}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"dx.resmayalias", i32 1}
+
+; DXC: - Name: SFI0
+; DXC-NEXT: Size: 8
+; DXC-NEXT: Flags:
+; DXC: UAVsAtEveryStage: true
+; DXC: NextUnusedBit: false
+; DXC: ...
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-lib-valver1.8.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-lib-valver1.8.ll
new file mode 100644
index 0000000000000..47da35b6c9d89
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-lib-valver1.8.ll
@@ -0,0 +1,27 @@
+; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
+
+; This test ensures that a library shader with a UAV does not get the module and
+; shader feature flag UAVsAtEveryStage when the DXIL validator version is >= 1.8
+
+target triple = "dxil-pc-shadermodel6.5-library"
+
+; CHECK: Combined Shader Flags for Module
+; CHECK-NEXT: Shader Flags Value: 0x00000000
+
+; CHECK-NOT: Note: shader requires additional functionality:
+; CHECK-NOT: UAVs at every shader stage
+
+; CHECK: Function test : 0x00000000
+define void @test() "hlsl.export" {
+ ; RWBuffer<float> Buf : register(u0, space0)
+ %buf0 = call target("dx.TypedBuffer", float, 1, 0, 1)
+ @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0t(
+ i32 0, i32 0, i32 1, i32 0, i1 false)
+ ret void
+}
+
+!dx.valver = !{!1}
+!1 = !{i32 1, i32 8}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"dx.resmayalias", i32 1}
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-vs.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-vs.ll
new file mode 100644
index 0000000000000..d3f556b62ed0c
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-vs.ll
@@ -0,0 +1,36 @@
+; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
+; TODO: Remove this comment and add 'RUN' to the line below once vertex shaders are supported by llc
+; llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
+
+; This test ensures that a Vertex shader with a UAV gets the module and
+; shader feature flag UAVsAtEveryStage
+
+target triple = "dxil-pc-shadermodel6.5-vertex"
+
+; CHECK: Combined Shader Flags for Module
+; CHECK-NEXT: Shader Flags Value: 0x00010000
+
+; CHECK: Note: shader requires additional functionality:
+; CHECK: UAVs at every shader stage
+
+; CHECK: Function VSMain : 0x00000000
+define void @VSMain() {
+ ; RWBuffer<float> Buf : register(u0, space0)
+ %buf0 = call target("dx.TypedBuffer", float, 1, 0, 1)
+ @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0t(
+ i32 0, i32 0, i32 1, i32 0, i1 false)
+ ret void
+}
+
+!dx.valver = !{!1}
+!1 = !{i32 1, i32 8}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"dx.resmayalias", i32 1}
+
+; DXC: - Name: SFI0
+; DXC-NEXT: Size: 8
+; DXC-NEXT: Flags:
+; DXC: UAVsAtEveryStage: true
+; DXC: NextUnusedBit: false
+; DXC: ...
More information about the llvm-commits
mailing list