Skip to content

Commit 747d4a9

Browse files
authored
[DirectX] Implement UseNativeLowPrecision shader flag analysis (#134288)
Fixes #112267 Implement the shader flag analysis to set the UseNativeLowPrecision DXIL module flag. The flag is only able to be set when the command-line flag `-enable-16bit-types` is passed to clang-dxc, or equivalently `-fnative-half-type` is passed to clang. When the command-line flag is passed, a module metadata flag called "dx.nativelowprec" is set to 1. The DXILShaderFlags shader flags analysis checks that the module metadata flag "dx.nativelowprec" is set to 1 and the DXIL Version is 1.2 or greater before setting the UseNativeLowPrecision DXIL module flag.
1 parent b88eef9 commit 747d4a9

File tree

5 files changed

+62
-11
lines changed

5 files changed

+62
-11
lines changed

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,11 +282,19 @@ void CGHLSLRuntime::addHLSLBufferLayoutType(const RecordType *StructType,
282282

283283
void CGHLSLRuntime::finishCodeGen() {
284284
auto &TargetOpts = CGM.getTarget().getTargetOpts();
285+
auto &LangOpts = CGM.getLangOpts();
285286
llvm::Module &M = CGM.getModule();
286287
Triple T(M.getTargetTriple());
287288
if (T.getArch() == Triple::ArchType::dxil)
288289
addDxilValVersion(TargetOpts.DxilValidatorVersion, M);
289290

291+
// NativeHalfType corresponds to the -fnative-half-type clang option which is
292+
// aliased by clang-dxc's -enable-16bit-types option. This option is used to
293+
// set the UseNativeLowPrecision DXIL module flag in the DirectX backend
294+
if (LangOpts.NativeHalfType)
295+
M.setModuleFlag(llvm::Module::ModFlagBehavior::Error, "dx.nativelowprec",
296+
1);
297+
290298
generateGlobalCtorDtorCalls();
291299
}
292300

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %clang_dxc -enable-16bit-types -T lib_6_3 -HV 202x -Vd -Xclang -emit-llvm %s | FileCheck %s --check-prefix=FLAG
2+
// RUN: %clang_dxc -T lib_6_3 -HV 202x -Vd -Xclang -emit-llvm %s | FileCheck %s --check-prefix=NOFLAG
3+
4+
// FLAG-DAG: ![[NLP:.*]] = !{i32 1, !"dx.nativelowprec", i32 1}
5+
// FLAG-DAG: !llvm.module.flags = !{{{.*}}![[NLP]]{{.*}}}
6+
7+
// NOFLAG-NOT: dx.nativelowprec

llvm/lib/Target/DirectX/DXILShaderFlags.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,13 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
188188
continue;
189189
}
190190

191+
// Set UseNativeLowPrecision using dx.nativelowprec module metadata
192+
if (auto *NativeLowPrec = mdconst::extract_or_null<ConstantInt>(
193+
M.getModuleFlag("dx.nativelowprec")))
194+
if (MMDI.DXILVersion >= VersionTuple(1, 2) &&
195+
NativeLowPrec->getValue() != 0)
196+
SCCSF.UseNativeLowPrecision = true;
197+
191198
ComputedShaderFlags CSF;
192199
for (const auto &BB : *F)
193200
for (const auto &I : BB)
Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
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
32

43
target triple = "dxil-pc-shadermodel6.7-library"
54

@@ -13,26 +12,19 @@ target triple = "dxil-pc-shadermodel6.7-library"
1312
;CHECK-NEXT: ; Shader Flags for Module Functions
1413

1514
;CHECK-LABEL: ; Function add_i16 : 0x00000020
16-
define i16 @add_i16(i16 %a, i16 %b) #0 {
15+
define i16 @add_i16(i16 %a, i16 %b) {
1716
%sum = add i16 %a, %b
1817
ret i16 %sum
1918
}
2019

2120
;CHECK-LABEL: ; Function add_i32 : 0x00000000
22-
define i32 @add_i32(i32 %a, i32 %b) #0 {
21+
define i32 @add_i32(i32 %a, i32 %b) {
2322
%sum = add i32 %a, %b
2423
ret i32 %sum
2524
}
2625

2726
;CHECK-LABEL: ; Function add_half : 0x00000020
28-
define half @add_half(half %a, half %b) #0 {
27+
define half @add_half(half %a, half %b) {
2928
%sum = fadd half %a, %b
3029
ret half %sum
3130
}
32-
33-
attributes #0 = { convergent norecurse nounwind "hlsl.export"}
34-
35-
; DXC: - Name: SFI0
36-
; DXC-NEXT: Size: 8
37-
; DXC-NOT: Flags:
38-
; DXC: ...
Lines changed: 37 additions & 0 deletions
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+
target triple = "dxil-pc-shadermodel6.7-library"
4+
5+
;CHECK: ; Combined Shader Flags for Module
6+
;CHECK-NEXT: ; Shader Flags Value: 0x00800020
7+
;CHECK-NEXT: ;
8+
;CHECK-NEXT: ; Note: shader requires additional functionality:
9+
;CHECK-NEXT: ; Note: extra DXIL module flags:
10+
;CHECK-NEXT: ; D3D11_1_SB_GLOBAL_FLAG_ENABLE_MINIMUM_PRECISION
11+
;CHECK-NEXT: ; Native 16bit types enabled
12+
;CHECK-NEXT: ;
13+
;CHECK-NEXT: ; Shader Flags for Module Functions
14+
15+
;CHECK-LABEL: ; Function add_i16 : 0x00800020
16+
define i16 @add_i16(i16 %a, i16 %b) {
17+
%sum = add i16 %a, %b
18+
ret i16 %sum
19+
}
20+
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) {
26+
%sum = add i32 %a, %b
27+
ret i32 %sum
28+
}
29+
30+
;CHECK-LABEL: ; Function add_half : 0x00800020
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 1}

0 commit comments

Comments
 (0)