Skip to content

Commit 3e4e365

Browse files
authored
[DirectX] Fix shader flag version-checking logic to match DXC (#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 - Add obj2yaml tests for the `Max64UAVs` shader flag
1 parent 60a1f5a commit 3e4e365

10 files changed

+92
-28
lines changed

llvm/lib/Target/DirectX/DXILShaderFlags.cpp

+9-8
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,10 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF,
132132
case Intrinsic::dx_resource_handlefrombinding: {
133133
dxil::ResourceTypeInfo &RTI = DRTM[cast<TargetExtType>(II->getType())];
134134

135-
// Set ResMayNotAlias if DXIL version >= 1.8 and function uses UAVs
135+
// Set ResMayNotAlias if DXIL validator version >= 1.8 and the function
136+
// uses UAVs
136137
if (!CSF.ResMayNotAlias && CanSetResMayNotAlias &&
137-
MMDI.DXILVersion >= VersionTuple(1, 8) && RTI.isUAV())
138+
MMDI.ValidatorVersion >= VersionTuple(1, 8) && RTI.isUAV())
138139
CSF.ResMayNotAlias = true;
139140

140141
switch (RTI.getResourceKind()) {
@@ -208,15 +209,15 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
208209
continue;
209210
}
210211

211-
// Set ResMayNotAlias to true if DXIL version < 1.8 and there are UAVs
212-
// present globally.
213-
if (CanSetResMayNotAlias && MMDI.DXILVersion < VersionTuple(1, 8))
212+
// Set ResMayNotAlias to true if DXIL validator version < 1.8 and there
213+
// are UAVs present globally.
214+
if (CanSetResMayNotAlias && MMDI.ValidatorVersion < VersionTuple(1, 8))
214215
SCCSF.ResMayNotAlias = !DRM.uavs().empty();
215216

216217
// Set UseNativeLowPrecision using dx.nativelowprec module metadata
217218
if (auto *NativeLowPrec = mdconst::extract_or_null<ConstantInt>(
218219
M.getModuleFlag("dx.nativelowprec")))
219-
if (MMDI.DXILVersion >= VersionTuple(1, 2) &&
220+
if (MMDI.ShaderModelVersion >= VersionTuple(6, 2) &&
220221
NativeLowPrec->getValue() != 0)
221222
SCCSF.UseNativeLowPrecision = true;
222223

@@ -259,9 +260,9 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
259260
// Set the Max64UAVs flag if the number of UAVs is > 8
260261
uint32_t NumUAVs = 0;
261262
for (auto &UAV : DRM.uavs())
262-
if (MMDI.DXILVersion < VersionTuple(1, 6))
263+
if (MMDI.ValidatorVersion < VersionTuple(1, 6))
263264
NumUAVs++;
264-
else // MMDI.DXILVersion >= VersionTuple(1, 6)
265+
else // MMDI.ValidatorVersion >= VersionTuple(1, 6)
265266
NumUAVs += UAV.getBinding().Size;
266267
if (NumUAVs > 8)
267268
CombinedSFMask.Max64UAVs = true;

llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-sm6_5.ll renamed to llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.5.ll

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
22

33
; This test makes sure that resource arrays only add 1 to the count of the
4-
; number of UAVs for setting the shader flag '64 UAV slots' when the shader
5-
; model version is < 6.6
4+
; number of UAVs for setting the shader flag '64 UAV slots' when the validator
5+
; version is < 1.6
66

7-
; Note: there is no feature flag here (only a module flag), so we don't have an
8-
; object test.
9-
10-
target triple = "dxil-pc-shadermodel6.5-library"
7+
target triple = "dxil-pc-shadermodel6.7-library"
118

129
; CHECK: Combined Shader Flags for Module
1310
; CHECK-NEXT: Shader Flags Value: 0x00000000
@@ -29,5 +26,10 @@ define void @test() "hlsl.export" {
2926
ret void
3027
}
3128

29+
; Set validator version to 1.5
30+
!dx.valver = !{!1}
31+
!1 = !{i32 1, i32 5}
32+
33+
; Set this flag to 1 to prevent the ResMayNotAlias flag from being set
3234
!llvm.module.flags = !{!0}
3335
!0 = !{i32 1, !"dx.resmayalias", i32 1}

llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-sm6_6.ll renamed to llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.6.ll

+17-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
2+
; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
23

34
; This test makes sure that resource arrays sizes are accounted for when
45
; counting the number of UAVs for setting the shader flag '64 UAV slots' when
5-
; the shader model version is >= 6.6
6+
; the validator version is >= 1.6
67

7-
; Note: there is no feature flag here (only a module flag), so we don't have an
8-
; object test.
9-
10-
target triple = "dxil-pc-shadermodel6.6-library"
8+
target triple = "dxil-pc-shadermodel6.7-library"
119

1210
; CHECK: Combined Shader Flags for Module
1311
; CHECK-NEXT: Shader Flags Value: 0x00008000
@@ -29,5 +27,19 @@ define void @test() "hlsl.export" {
2927
ret void
3028
}
3129

30+
; Set validator version to 1.6
31+
!dx.valver = !{!1}
32+
!1 = !{i32 1, i32 6}
33+
34+
; Set this flag to 1 to prevent the ResMayNotAlias flag from being set
3235
!llvm.module.flags = !{!0}
3336
!0 = !{i32 1, !"dx.resmayalias", i32 1}
37+
38+
; DXC: - Name: SFI0
39+
; DXC-NEXT: Size: 8
40+
; DXC-NEXT: Flags:
41+
; DXC-NOT: {{[A-Za-z]+: +true}}
42+
; DXC: Max64UAVs: true
43+
; DXC-NOT: {{[A-Za-z]+: +true}}
44+
; DXC: NextUnusedBit: false
45+
; DXC: ...

llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs.ll

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
2+
; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
23

34
; This test makes sure that the shader flag '64 UAV slots' is set when there are
45
; more than 8 UAVs in the module.
56

6-
; Note: there is no feature flag here (only a module flag), so we don't have an
7-
; object test.
8-
97
target triple = "dxil-pc-shadermodel6.7-library"
108

119
; CHECK: Combined Shader Flags for Module
@@ -58,3 +56,12 @@ define void @test() "hlsl.export" {
5856

5957
!llvm.module.flags = !{!0}
6058
!0 = !{i32 1, !"dx.resmayalias", i32 1}
59+
60+
; DXC: - Name: SFI0
61+
; DXC-NEXT: Size: 8
62+
; DXC-NEXT: Flags:
63+
; DXC-NOT: {{[A-Za-z]+: +true}}
64+
; DXC: Max64UAVs: true
65+
; DXC-NOT: {{[A-Za-z]+: +true}}
66+
; DXC: NextUnusedBit: false
67+
; DXC: ...

llvm/test/CodeGen/DirectX/ShaderFlags/res-may-alias-0.ll

+2
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,11 @@ define float @loadSRV() #0 {
3535
}
3636

3737
!llvm.module.flags = !{!0}
38+
!dx.valver = !{!1}
3839

3940
; dx.resmayalias should never appear with a value of 0.
4041
; But if it does, ensure that it has no effect.
4142
!0 = !{i32 1, !"dx.resmayalias", i32 0}
43+
!1 = !{i32 1, i32 8}
4244

4345
attributes #0 = { convergent norecurse nounwind "hlsl.export"}

llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.6.ll renamed to llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.6.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
22

33
; This test checks to ensure the behavior of the DXIL shader flag analysis
4-
; for the flag ResMayNotAlias is correct when the DXIL Version is 1.6. The
4+
; for the flag ResMayNotAlias is correct when the DXIL Version is < 1.7. The
55
; ResMayNotAlias flag (0x20000000) should not be set at all.
66

77
target triple = "dxil-pc-shadermodel6.6-library"

llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.7.ll renamed to llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.7.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
22

33
; This test checks to ensure the behavior of the DXIL shader flag analysis
4-
; for the flag ResMayNotAlias is correct when the DXIL Version is 1.7. The
4+
; for the flag ResMayNotAlias is correct when the DXIL Version is >= 1.7. The
55
; ResMayNotAlias flag (0x20000000) should be set on all functions if there are
66
; one or more UAVs present globally in the module.
77

llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-shadermodel6.8.ll renamed to llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-valver1.8.ll

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
22

3-
; This test checks to ensure the behavior of the DXIL shader flag analysis
4-
; for the flag ResMayNotAlias is correct when the DXIL Version is 1.8. The
5-
; ResMayNotAlias flag (0x20000000) should only be set when a function uses a
3+
; This test checks to ensure the behavior of the DXIL shader flag analysis for
4+
; the flag ResMayNotAlias is correct when the DXIL validator version is >= 1.8.
5+
; The ResMayNotAlias flag (0x20000000) should only be set when a function uses a
66
; UAV.
77

8-
target triple = "dxil-pc-shadermodel6.8-library"
8+
target triple = "dxil-pc-shadermodel6.7-library"
99

1010
; CHECK: Combined Shader Flags for Module
1111
; CHECK-NEXT: Shader Flags Value: 0x200000010
@@ -35,4 +35,7 @@ define float @loadSRV() #0 {
3535
ret float %val
3636
}
3737

38+
!dx.valver = !{!1}
39+
!1 = !{i32 1, i32 8}
40+
3841
attributes #0 = { convergent norecurse nounwind "hlsl.export"}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
2+
3+
; Check that when the dx.nativelowprec module flag is set to 0, the module-level
4+
; shader flag UseNativeLowPrecision is not set
5+
6+
target triple = "dxil-pc-shadermodel6.7-library"
7+
8+
;CHECK: ; Combined Shader Flags for Module
9+
;CHECK-NEXT: ; Shader Flags Value: 0x00000020
10+
;CHECK-NEXT: ;
11+
;CHECK-NEXT: ; Note: shader requires additional functionality:
12+
;CHECK-NEXT: ; Note: extra DXIL module flags:
13+
;CHECK-NEXT: ; D3D11_1_SB_GLOBAL_FLAG_ENABLE_MINIMUM_PRECISION
14+
;CHECK-NOT: ; Native 16bit types enabled
15+
;CHECK-NEXT: ;
16+
;CHECK-NEXT: ; Shader Flags for Module Functions
17+
18+
;CHECK-LABEL: ; Function add_i16 : 0x00000020
19+
define i16 @add_i16(i16 %a, i16 %b) {
20+
%sum = add i16 %a, %b
21+
ret i16 %sum
22+
}
23+
24+
;CHECK-LABEL: ; Function add_i32 : 0x00000000
25+
define i32 @add_i32(i32 %a, i32 %b) {
26+
%sum = add i32 %a, %b
27+
ret i32 %sum
28+
}
29+
30+
;CHECK-LABEL: ; Function add_half : 0x00000020
31+
define half @add_half(half %a, half %b) {
32+
%sum = fadd half %a, %b
33+
ret half %sum
34+
}
35+
36+
!llvm.module.flags = !{!0}
37+
!0 = !{i32 1, !"dx.nativelowprec", i32 0}

0 commit comments

Comments
 (0)