Skip to content

Commit 80fa621

Browse files
Icohedronbogner
andauthored
[DirectX] Set shader feature flags MinimumPrecision and NativeLowPrecision, and refactor the logic for setting low-precision-related flags (#139623)
Fixes #138997 and does refactoring for low-precision-related flags. The shader feature flags MinimumPrecision and NativeLowPrecision were not being set, leading to validation errors. This PR sets these shader feature flags [as in DXC](https://github.com/microsoft/DirectXShaderCompiler/blob/377c4ca6d82adb83bf2eaf978a7040443848d6fd/lib/DXIL/DxilShaderFlags.cpp#L58-L63) and adds tests for them. This PR also performs some refactoring of low-precision-related flags to make it less confusing. - The `UseNativeLowPrecision` DXIL module flag has been renamed to `NativeLowPrecisionMode` to imply that it is setting some execution state which the module should be interpreted with - The LLVM module flag `dx.nativelowprec` is now read only once and sets a bool to be used by `updateFunctionFlags()` and for setting the DXIL module flag `NativeLowPrecisionMode` - The `MinimumPrecision`, `NativeLowPrecision`, and `LowPrecisionPresent` shader feature flags are all set together under `updateFunctionFlags()` - Moved the logic for setting DXIL module flags `NativeLowPrecisionMode` and `ResMayNotAlias` out of the per-function loop and placed it alongside the logic for setting other DXIL module flags (`DisableOptimizations`, `Max64UAVs`, and `UAVsAtEveryStage` flags) --------- Co-authored-by: Justin Bogner <[email protected]>
1 parent bf0655f commit 80fa621

File tree

7 files changed

+97
-47
lines changed

7 files changed

+97
-47
lines changed

llvm/include/llvm/BinaryFormat/DXContainerConstants.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ SHADER_FEATURE_FLAG(14, 19, WaveOps, "Wave level operations")
3434
SHADER_FEATURE_FLAG(15, 20, Int64Ops, "64-Bit integer")
3535
SHADER_FEATURE_FLAG(16, 21, ViewID, "View Instancing")
3636
SHADER_FEATURE_FLAG(17, 22, Barycentrics, "Barycentrics")
37-
SHADER_FEATURE_FLAG(18, -1, NativeLowPrecision, "Use native low precision")
37+
SHADER_FEATURE_FLAG(18, -1, NativeLowPrecision, "Native low-precision data types")
3838
SHADER_FEATURE_FLAG(19, 24, ShadingRate, "Shading Rate")
3939
SHADER_FEATURE_FLAG(20, 25, Raytracing_Tier_1_1, "Raytracing tier 1.1 features")
4040
SHADER_FEATURE_FLAG(21, 26, SamplerFeedback, "Sampler feedback")
@@ -115,9 +115,9 @@ DXIL_MODULE_FLAG( 0, DisableOptimizations, "Disable shader optimizations")
115115
DXIL_MODULE_FLAG( 1, DisableMathRefactoring, "Disable math refactoring")
116116
DXIL_MODULE_FLAG( 3, ForceEarlyDepthStencil, "Force early depth-stencil test")
117117
DXIL_MODULE_FLAG( 4, EnableRawAndStructuredBuffers, "Raw and structured buffers")
118-
DXIL_MODULE_FLAG( 5, LowPrecisionPresent, "Low-precision data types")
118+
DXIL_MODULE_FLAG( 5, LowPrecisionPresent, "Low-precision data types present")
119119
DXIL_MODULE_FLAG( 8, AllResourcesBound, "All resources bound for the duration of shader execution")
120-
DXIL_MODULE_FLAG(23, UseNativeLowPrecision, "Use native low precision")
120+
DXIL_MODULE_FLAG(23, NativeLowPrecisionMode, "Enable native low-precision data types")
121121
DXIL_MODULE_FLAG(33, ResMayNotAlias, "Any UAV may not alias any other UAV")
122122

123123
#undef DXIL_MODULE_FLAG

llvm/lib/Target/DirectX/DXILShaderFlags.cpp

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,13 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF,
142142
}
143143
}
144144

145+
if (CSF.LowPrecisionPresent) {
146+
if (CanSetNativeLowPrecisionMode)
147+
CSF.NativeLowPrecision = true;
148+
else
149+
CSF.MinimumPrecision = true;
150+
}
151+
145152
if (!CSF.Int64Ops)
146153
CSF.Int64Ops = I.getType()->isIntegerTy(64);
147154

@@ -206,13 +213,20 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
206213
const ModuleMetadataInfo &MMDI) {
207214

208215
CanSetResMayNotAlias = MMDI.DXILVersion >= VersionTuple(1, 7);
209-
210-
// Check if -res-may-alias was provided on the command line.
211-
// The command line option will set the dx.resmayalias module flag to 1.
212-
if (auto *RMA = mdconst::extract_or_null<ConstantInt>(
216+
// The command line option -res-may-alias will set the dx.resmayalias module
217+
// flag to 1, thereby disabling the ability to set the ResMayNotAlias flag
218+
if (auto *ResMayAlias = mdconst::extract_or_null<ConstantInt>(
213219
M.getModuleFlag("dx.resmayalias")))
214-
if (RMA->getValue() != 0)
215-
CanSetResMayNotAlias = false;
220+
CanSetResMayNotAlias = !ResMayAlias->getValue().getBoolValue();
221+
222+
// NativeLowPrecisionMode can only be set when the command line option
223+
// -enable-16bit-types is provided. This is indicated by the dx.nativelowprec
224+
// module flag being set
225+
CanSetNativeLowPrecisionMode = false;
226+
if (auto *NativeLowPrec = mdconst::extract_or_null<ConstantInt>(
227+
M.getModuleFlag("dx.nativelowprec")))
228+
if (MMDI.ShaderModelVersion >= VersionTuple(6, 2))
229+
CanSetNativeLowPrecisionMode = NativeLowPrec->getValue().getBoolValue();
216230

217231
CallGraph CG(M);
218232

@@ -238,18 +252,6 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
238252
continue;
239253
}
240254

241-
// Set ResMayNotAlias to true if DXIL validator version < 1.8 and there
242-
// are UAVs present globally.
243-
if (CanSetResMayNotAlias && MMDI.ValidatorVersion < VersionTuple(1, 8))
244-
SCCSF.ResMayNotAlias = !DRM.uavs().empty();
245-
246-
// Set UseNativeLowPrecision using dx.nativelowprec module metadata
247-
if (auto *NativeLowPrec = mdconst::extract_or_null<ConstantInt>(
248-
M.getModuleFlag("dx.nativelowprec")))
249-
if (MMDI.ShaderModelVersion >= VersionTuple(6, 2) &&
250-
NativeLowPrec->getValue() != 0)
251-
SCCSF.UseNativeLowPrecision = true;
252-
253255
ComputedShaderFlags CSF;
254256
for (const auto &BB : *F)
255257
for (const auto &I : BB)
@@ -286,6 +288,17 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
286288
*(EntryFunProps.Entry), "Inconsistent optnone attribute "));
287289
}
288290

291+
// Set ResMayNotAlias to true if DXIL validator version < 1.8 and there
292+
// are UAVs present globally.
293+
if (CanSetResMayNotAlias && MMDI.ValidatorVersion < VersionTuple(1, 8))
294+
CombinedSFMask.ResMayNotAlias = !DRM.uavs().empty();
295+
296+
// Set the module flag that enables native low-precision execution mode. This
297+
// is needed even if the module does not use 16-bit types because a
298+
// corresponding debug module may include 16-bit types, and tools that use the
299+
// debug module may expect it to have the same flags as the original
300+
CombinedSFMask.NativeLowPrecisionMode = CanSetNativeLowPrecisionMode;
301+
289302
// Set the Max64UAVs flag if the number of UAVs is > 8
290303
uint32_t NumUAVs = 0;
291304
for (auto &UAV : DRM.uavs())

llvm/lib/Target/DirectX/DXILShaderFlags.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,10 @@ struct ModuleShaderFlags {
9191
const ComputedShaderFlags &getCombinedFlags() const { return CombinedSFMask; }
9292

9393
private:
94-
bool CanSetResMayNotAlias;
94+
// Booleans set by module flags
95+
bool CanSetResMayNotAlias; // dx.resmayalias
96+
bool CanSetNativeLowPrecisionMode; // dx.nativelowprec
97+
9598
/// Map of Function-Shader Flag Mask pairs representing properties of each of
9699
/// the functions in the module. Shader Flags of each function represent both
97100
/// module-level and function-level flags
Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,44 @@
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
3+
4+
; Check that when the dx.nativelowprec module flag is not specified, the
5+
; module-level shader flag UseNativeLowPrecision is not set, and the
6+
; MinimumPrecision feature flag is set due to the presence of half and i16
7+
; without native low precision.
28

39
target triple = "dxil-pc-shadermodel6.7-library"
410

511
;CHECK: ; Combined Shader Flags for Module
612
;CHECK-NEXT: ; Shader Flags Value: 0x00000020
713
;CHECK-NEXT: ;
814
;CHECK-NEXT: ; Note: shader requires additional functionality:
15+
;CHECK-NEXT: ; Minimum-precision data types
916
;CHECK-NEXT: ; Note: extra DXIL module flags:
10-
;CHECK-NEXT: ; Low-precision data types
17+
;CHECK-NEXT: ; Low-precision data types present
1118
;CHECK-NEXT: ;
1219
;CHECK-NEXT: ; Shader Flags for Module Functions
1320

1421
;CHECK-LABEL: ; Function add_i16 : 0x00000020
15-
define i16 @add_i16(i16 %a, i16 %b) {
22+
define i16 @add_i16(i16 %a, i16 %b) "hlsl.export" {
1623
%sum = add i16 %a, %b
1724
ret i16 %sum
1825
}
1926

2027
;CHECK-LABEL: ; Function add_i32 : 0x00000000
21-
define i32 @add_i32(i32 %a, i32 %b) {
28+
define i32 @add_i32(i32 %a, i32 %b) "hlsl.export" {
2229
%sum = add i32 %a, %b
2330
ret i32 %sum
2431
}
2532

2633
;CHECK-LABEL: ; Function add_half : 0x00000020
27-
define half @add_half(half %a, half %b) {
34+
define half @add_half(half %a, half %b) "hlsl.export" {
2835
%sum = fadd half %a, %b
2936
ret half %sum
3037
}
38+
39+
; DXC: - Name: SFI0
40+
; DXC-NEXT: Size: 8
41+
; DXC-NEXT: Flags:
42+
; DXC: MinimumPrecision: true
43+
; DXC: NativeLowPrecision: false
44+
; DXC: ...

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

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

99
target triple = "dxil-pc-shadermodel6.7-library"
@@ -19,7 +19,7 @@ target triple = "dxil-pc-shadermodel6.7-library"
1919
; CHECK: Any UAV may not alias any other UAV
2020
;
2121

22-
; CHECK: Function loadUAV : 0x200000000
22+
; CHECK: Function loadUAV : 0x00000000
2323
define float @loadUAV() #0 {
2424
%res = call target("dx.TypedBuffer", float, 1, 0, 0)
2525
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
@@ -29,7 +29,7 @@ define float @loadUAV() #0 {
2929
ret float %val
3030
}
3131

32-
; CHECK: Function loadSRV : 0x200000010
32+
; CHECK: Function loadSRV : 0x00000010
3333
define float @loadSRV() #0 {
3434
%res = tail call target("dx.RawBuffer", float, 0, 0)
3535
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,47 @@
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
; Check that when the dx.nativelowprec module flag is set to 0, the module-level
4-
; shader flag UseNativeLowPrecision is not set
5+
; shader flag UseNativeLowPrecision is not set, and the MinimumPrecision feature
6+
; flag is set due to the presence of half and i16 without native low precision.
57

68
target triple = "dxil-pc-shadermodel6.7-library"
79

810
;CHECK: ; Combined Shader Flags for Module
911
;CHECK-NEXT: ; Shader Flags Value: 0x00000020
1012
;CHECK-NEXT: ;
1113
;CHECK-NEXT: ; Note: shader requires additional functionality:
14+
;CHECK-NEXT: ; Minimum-precision data types
1215
;CHECK-NEXT: ; Note: extra DXIL module flags:
13-
;CHECK-NEXT: ; Low-precision data types
14-
;CHECK-NOT: ; Native 16bit types enabled
16+
;CHECK-NEXT: ; Low-precision data types present
17+
;CHECK-NOT: ; Enable native low-precision data types
1518
;CHECK-NEXT: ;
1619
;CHECK-NEXT: ; Shader Flags for Module Functions
1720

1821
;CHECK-LABEL: ; Function add_i16 : 0x00000020
19-
define i16 @add_i16(i16 %a, i16 %b) {
22+
define i16 @add_i16(i16 %a, i16 %b) "hlsl.export" {
2023
%sum = add i16 %a, %b
2124
ret i16 %sum
2225
}
2326

2427
;CHECK-LABEL: ; Function add_i32 : 0x00000000
25-
define i32 @add_i32(i32 %a, i32 %b) {
28+
define i32 @add_i32(i32 %a, i32 %b) "hlsl.export" {
2629
%sum = add i32 %a, %b
2730
ret i32 %sum
2831
}
2932

3033
;CHECK-LABEL: ; Function add_half : 0x00000020
31-
define half @add_half(half %a, half %b) {
34+
define half @add_half(half %a, half %b) "hlsl.export" {
3235
%sum = fadd half %a, %b
3336
ret half %sum
3437
}
3538

3639
!llvm.module.flags = !{!0}
3740
!0 = !{i32 1, !"dx.nativelowprec", i32 0}
41+
42+
; DXC: - Name: SFI0
43+
; DXC-NEXT: Size: 8
44+
; DXC-NEXT: Flags:
45+
; DXC: MinimumPrecision: true
46+
; DXC: NativeLowPrecision: false
47+
; DXC: ...
Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,47 @@
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
3+
4+
; Check that when the dx.nativelowprec module flag is set to 1, the module-level
5+
; shader flag UseNativeLowPrecision is set, and the NativeLowPrecision feature
6+
; flag is set
27

38
target triple = "dxil-pc-shadermodel6.7-library"
49

510
;CHECK: ; Combined Shader Flags for Module
611
;CHECK-NEXT: ; Shader Flags Value: 0x00800020
712
;CHECK-NEXT: ;
813
;CHECK-NEXT: ; Note: shader requires additional functionality:
14+
;CHECK-NEXT: ; Native low-precision data types
915
;CHECK-NEXT: ; Note: extra DXIL module flags:
10-
;CHECK-NEXT: ; Low-precision data types
11-
;CHECK-NEXT: ; Use native low precision
16+
;CHECK-NEXT: ; Low-precision data types present
17+
;CHECK-NEXT: ; Enable native low-precision data types
1218
;CHECK-NEXT: ;
1319
;CHECK-NEXT: ; Shader Flags for Module Functions
1420

15-
;CHECK-LABEL: ; Function add_i16 : 0x00800020
16-
define i16 @add_i16(i16 %a, i16 %b) {
21+
;CHECK-LABEL: ; Function add_i16 : 0x00000020
22+
define i16 @add_i16(i16 %a, i16 %b) "hlsl.export" {
1723
%sum = add i16 %a, %b
1824
ret i16 %sum
1925
}
2026

21-
; NOTE: The flag for native low precision (0x80000) is set for every function
22-
; in the module regardless of whether or not the function uses low precision
23-
; data types (flag 0x20). This matches the behavior in DXC
24-
;CHECK-LABEL: ; Function add_i32 : 0x00800000
25-
define i32 @add_i32(i32 %a, i32 %b) {
27+
;CHECK-LABEL: ; Function add_i32 : 0x00000000
28+
define i32 @add_i32(i32 %a, i32 %b) "hlsl.export" {
2629
%sum = add i32 %a, %b
2730
ret i32 %sum
2831
}
2932

30-
;CHECK-LABEL: ; Function add_half : 0x00800020
31-
define half @add_half(half %a, half %b) {
33+
;CHECK-LABEL: ; Function add_half : 0x00000020
34+
define half @add_half(half %a, half %b) "hlsl.export" {
3235
%sum = fadd half %a, %b
3336
ret half %sum
3437
}
3538

3639
!llvm.module.flags = !{!0}
3740
!0 = !{i32 1, !"dx.nativelowprec", i32 1}
41+
42+
; DXC: - Name: SFI0
43+
; DXC-NEXT: Size: 8
44+
; DXC-NEXT: Flags:
45+
; DXC: MinimumPrecision: false
46+
; DXC: NativeLowPrecision: true
47+
; DXC: ...

0 commit comments

Comments
 (0)