-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[DirectX] Implement Max64UAVs shader flag analysis #136229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-backend-directx Author: Deric C. (Icohedron) ChangesFixes #114553 This implementation replicates the behavior of DXC in setting the The behavior of how UAV (resource) arrays are counted differs based on Shader Model version:
I initially thought the complete implementation of this analysis may be blocked by the resource arrays implementation, but it seems that it is not the case, as the Full diff: https://github.com/llvm/llvm-project/pull/136229.diff 4 Files Affected:
diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
index 1331b0d1d852b..282b9dcf6de2b 100644
--- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
+++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
@@ -255,6 +255,16 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
EntryFunProps.Entry->getContext().diagnose(DiagnosticInfoUnsupported(
*(EntryFunProps.Entry), "Inconsistent optnone attribute "));
}
+
+ // 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))
+ NumUAVs++;
+ else // MMDI.DXILVersion >= VersionTuple(1, 6)
+ NumUAVs += UAV.getBinding().Size;
+ if (NumUAVs > 8)
+ CombinedSFMask.Max64UAVs = true;
}
void ComputedShaderFlags::print(raw_ostream &OS) const {
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-sm6_5.ll
new file mode 100644
index 0000000000000..5b978d67866be
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-sm6_5.ll
@@ -0,0 +1,33 @@
+; 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
+
+; 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"
+
+; CHECK: Combined Shader Flags for Module
+; CHECK-NEXT: Shader Flags Value: 0x00000000
+
+; CHECK-NOT: Note: shader requires additional functionality:
+; CHECK-NOT: 64 UAV slots
+
+; 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)
+
+ ; RWBuffer<float> Buf[8] : register(u1, space0)
+ %buf1 = call target("dx.TypedBuffer", float, 1, 0, 1)
+ @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0t(
+ i32 0, i32 1, i32 8, i32 0, i1 false)
+ ret void
+}
+
+!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-sm6_6.ll
new file mode 100644
index 0000000000000..4b901a78e6ea4
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-sm6_6.ll
@@ -0,0 +1,33 @@
+; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
+
+; 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
+
+; 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"
+
+; CHECK: Combined Shader Flags for Module
+; CHECK-NEXT: Shader Flags Value: 0x00008000
+
+; CHECK: Note: shader requires additional functionality:
+; CHECK: 64 UAV slots
+
+; 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)
+
+ ; RWBuffer<float> Buf[8] : register(u1, space0)
+ %buf1 = call target("dx.TypedBuffer", float, 1, 0, 1)
+ @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0t(
+ i32 0, i32 1, i32 8, i32 0, i1 false)
+ ret void
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"dx.resmayalias", i32 1}
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs.ll
new file mode 100644
index 0000000000000..c002ff2851452
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs.ll
@@ -0,0 +1,60 @@
+; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
+
+; This test makes sure that the shader flag '64 UAV slots' is set when there are
+; more than 8 UAVs in the module.
+
+; Note: there is no feature flag here (only a module flag), so we don't have an
+; object test.
+
+target triple = "dxil-pc-shadermodel6.7-library"
+
+; CHECK: Combined Shader Flags for Module
+; CHECK-NEXT: Shader Flags Value: 0x00008000
+
+; CHECK: Note: shader requires additional functionality:
+; CHECK: 64 UAV slots
+
+; Note: 64 UAV slots does not get set per-function
+; 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)
+ ; RWBuffer<float> Buf : register(u1, space0)
+ %buf1 = call target("dx.TypedBuffer", float, 1, 0, 1)
+ @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0t(
+ i32 0, i32 1, i32 1, i32 0, i1 false)
+ ; RWBuffer<float> Buf : register(u2, space0)
+ %buf2 = call target("dx.TypedBuffer", float, 1, 0, 1)
+ @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0t(
+ i32 0, i32 2, i32 1, i32 0, i1 false)
+ ; RWBuffer<float> Buf : register(u3, space0)
+ %buf3 = call target("dx.TypedBuffer", float, 1, 0, 1)
+ @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0t(
+ i32 0, i32 3, i32 1, i32 0, i1 false)
+ ; RWBuffer<float> Buf : register(u4, space0)
+ %buf4 = call target("dx.TypedBuffer", float, 1, 0, 1)
+ @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0t(
+ i32 0, i32 4, i32 1, i32 0, i1 false)
+ ; RWBuffer<float> Buf : register(u5, space0)
+ %buf5 = call target("dx.TypedBuffer", float, 1, 0, 1)
+ @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0t(
+ i32 0, i32 5, i32 1, i32 0, i1 false)
+ ; RWBuffer<float> Buf : register(u6, space0)
+ %buf6 = call target("dx.TypedBuffer", float, 1, 0, 1)
+ @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0t(
+ i32 0, i32 6, i32 1, i32 0, i1 false)
+ ; RWBuffer<float> Buf : register(u7, space0)
+ %buf7 = call target("dx.TypedBuffer", float, 1, 0, 1)
+ @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0t(
+ i32 0, i32 7, i32 1, i32 0, i1 false)
+ ; RWBuffer<float> Buf : register(u8, space0)
+ %buf8 = call target("dx.TypedBuffer", float, 1, 0, 1)
+ @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0t(
+ i32 0, i32 8, i32 1, i32 0, i1 false)
+ ret void
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"dx.resmayalias", i32 1}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
Fixes [llvm#114553](llvm#114553) This implementation replicates the behavior of DXC in setting the `m_b64UAVs` flag: the `Max64UAVs` DXIL module flag is set in the presence of more than 8 UAVs in a DXIL module. The behavior of how UAV (resource) arrays are counted differs based on Shader Model version: - If Shader Model < 6.6, then a UAV array counts as a single UAV regardless of its range size - if Shader Model >= 6.6, then a UAV array contributes its range size to the total number of UAVs I initially thought the complete implementation of this analysis may be blocked by the resource arrays implementation, but it seems that it is not the case, as the `@llvm.dx.resource.handle*` already includes a range size argument.
Fixes [llvm#114553](llvm#114553) This implementation replicates the behavior of DXC in setting the `m_b64UAVs` flag: the `Max64UAVs` DXIL module flag is set in the presence of more than 8 UAVs in a DXIL module. The behavior of how UAV (resource) arrays are counted differs based on Shader Model version: - If Shader Model < 6.6, then a UAV array counts as a single UAV regardless of its range size - if Shader Model >= 6.6, then a UAV array contributes its range size to the total number of UAVs I initially thought the complete implementation of this analysis may be blocked by the resource arrays implementation, but it seems that it is not the case, as the `@llvm.dx.resource.handle*` already includes a range size argument.
Fixes [llvm#114553](llvm#114553) This implementation replicates the behavior of DXC in setting the `m_b64UAVs` flag: the `Max64UAVs` DXIL module flag is set in the presence of more than 8 UAVs in a DXIL module. The behavior of how UAV (resource) arrays are counted differs based on Shader Model version: - If Shader Model < 6.6, then a UAV array counts as a single UAV regardless of its range size - if Shader Model >= 6.6, then a UAV array contributes its range size to the total number of UAVs I initially thought the complete implementation of this analysis may be blocked by the resource arrays implementation, but it seems that it is not the case, as the `@llvm.dx.resource.handle*` already includes a range size argument.
Fixes #114553
This implementation replicates the behavior of DXC in setting the
m_b64UAVs
flag: theMax64UAVs
DXIL module flag is set in the presence of more than 8 UAVs in a DXIL module.The behavior of how UAV (resource) arrays are counted differs based on Shader Model version:
I initially thought the complete implementation of this analysis may be blocked by the resource arrays implementation, but it seems that it is not the case, as the
@llvm.dx.resource.handle*
already includes a range size argument.