[llvm] 747d4a9 - [DirectX] Implement UseNativeLowPrecision shader flag analysis (#134288)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 9 18:14:28 PDT 2025
Author: Deric C.
Date: 2025-04-09T18:14:23-07:00
New Revision: 747d4a952bf7ed4adec72ddf3c9038aeff4fe8ee
URL: https://github.com/llvm/llvm-project/commit/747d4a952bf7ed4adec72ddf3c9038aeff4fe8ee
DIFF: https://github.com/llvm/llvm-project/commit/747d4a952bf7ed4adec72ddf3c9038aeff4fe8ee.diff
LOG: [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.
Added:
clang/test/CodeGenHLSL/enable-16bit-types.hlsl
llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision.ll
Modified:
clang/lib/CodeGen/CGHLSLRuntime.cpp
llvm/lib/Target/DirectX/DXILShaderFlags.cpp
llvm/test/CodeGen/DirectX/ShaderFlags/low-precision.ll
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 3b1810b62a2cd..77700ea3a676d 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -282,11 +282,19 @@ void CGHLSLRuntime::addHLSLBufferLayoutType(const RecordType *StructType,
void CGHLSLRuntime::finishCodeGen() {
auto &TargetOpts = CGM.getTarget().getTargetOpts();
+ auto &LangOpts = CGM.getLangOpts();
llvm::Module &M = CGM.getModule();
Triple T(M.getTargetTriple());
if (T.getArch() == Triple::ArchType::dxil)
addDxilValVersion(TargetOpts.DxilValidatorVersion, M);
+ // NativeHalfType corresponds to the -fnative-half-type clang option which is
+ // aliased by clang-dxc's -enable-16bit-types option. This option is used to
+ // set the UseNativeLowPrecision DXIL module flag in the DirectX backend
+ if (LangOpts.NativeHalfType)
+ M.setModuleFlag(llvm::Module::ModFlagBehavior::Error, "dx.nativelowprec",
+ 1);
+
generateGlobalCtorDtorCalls();
}
diff --git a/clang/test/CodeGenHLSL/enable-16bit-types.hlsl b/clang/test/CodeGenHLSL/enable-16bit-types.hlsl
new file mode 100644
index 0000000000000..9b5c742f9dacd
--- /dev/null
+++ b/clang/test/CodeGenHLSL/enable-16bit-types.hlsl
@@ -0,0 +1,7 @@
+// RUN: %clang_dxc -enable-16bit-types -T lib_6_3 -HV 202x -Vd -Xclang -emit-llvm %s | FileCheck %s --check-prefix=FLAG
+// RUN: %clang_dxc -T lib_6_3 -HV 202x -Vd -Xclang -emit-llvm %s | FileCheck %s --check-prefix=NOFLAG
+
+// FLAG-DAG: ![[NLP:.*]] = !{i32 1, !"dx.nativelowprec", i32 1}
+// FLAG-DAG: !llvm.module.flags = !{{{.*}}![[NLP]]{{.*}}}
+
+// NOFLAG-NOT: dx.nativelowprec
diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
index babf495220393..2ca428672e1c4 100644
--- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
+++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
@@ -188,6 +188,13 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
continue;
}
+ // Set UseNativeLowPrecision using dx.nativelowprec module metadata
+ if (auto *NativeLowPrec = mdconst::extract_or_null<ConstantInt>(
+ M.getModuleFlag("dx.nativelowprec")))
+ if (MMDI.DXILVersion >= VersionTuple(1, 2) &&
+ NativeLowPrec->getValue() != 0)
+ SCCSF.UseNativeLowPrecision = true;
+
ComputedShaderFlags CSF;
for (const auto &BB : *F)
for (const auto &I : BB)
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/low-precision.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/low-precision.ll
index fd25a165bfe8d..52e00b107bb82 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/low-precision.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/low-precision.ll
@@ -1,5 +1,4 @@
; 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
target triple = "dxil-pc-shadermodel6.7-library"
@@ -13,26 +12,19 @@ target triple = "dxil-pc-shadermodel6.7-library"
;CHECK-NEXT: ; Shader Flags for Module Functions
;CHECK-LABEL: ; Function add_i16 : 0x00000020
-define i16 @add_i16(i16 %a, i16 %b) #0 {
+define i16 @add_i16(i16 %a, i16 %b) {
%sum = add i16 %a, %b
ret i16 %sum
}
;CHECK-LABEL: ; Function add_i32 : 0x00000000
-define i32 @add_i32(i32 %a, i32 %b) #0 {
+define i32 @add_i32(i32 %a, i32 %b) {
%sum = add i32 %a, %b
ret i32 %sum
}
;CHECK-LABEL: ; Function add_half : 0x00000020
-define half @add_half(half %a, half %b) #0 {
+define half @add_half(half %a, half %b) {
%sum = fadd half %a, %b
ret half %sum
}
-
-attributes #0 = { convergent norecurse nounwind "hlsl.export"}
-
-; DXC: - Name: SFI0
-; DXC-NEXT: Size: 8
-; DXC-NOT: Flags:
-; DXC: ...
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision.ll
new file mode 100644
index 0000000000000..98e9a5fa7b241
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision.ll
@@ -0,0 +1,37 @@
+; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
+
+target triple = "dxil-pc-shadermodel6.7-library"
+
+;CHECK: ; Combined Shader Flags for Module
+;CHECK-NEXT: ; Shader Flags Value: 0x00800020
+;CHECK-NEXT: ;
+;CHECK-NEXT: ; Note: shader requires additional functionality:
+;CHECK-NEXT: ; Note: extra DXIL module flags:
+;CHECK-NEXT: ; D3D11_1_SB_GLOBAL_FLAG_ENABLE_MINIMUM_PRECISION
+;CHECK-NEXT: ; Native 16bit types enabled
+;CHECK-NEXT: ;
+;CHECK-NEXT: ; Shader Flags for Module Functions
+
+;CHECK-LABEL: ; Function add_i16 : 0x00800020
+define i16 @add_i16(i16 %a, i16 %b) {
+ %sum = add i16 %a, %b
+ ret i16 %sum
+}
+
+; NOTE: The flag for native low precision (0x80000) is set for every function
+; in the module regardless of whether or not the function uses low precision
+; data types (flag 0x20). This matches the behavior in DXC
+;CHECK-LABEL: ; Function add_i32 : 0x00800000
+define i32 @add_i32(i32 %a, i32 %b) {
+ %sum = add i32 %a, %b
+ ret i32 %sum
+}
+
+;CHECK-LABEL: ; Function add_half : 0x00800020
+define half @add_half(half %a, half %b) {
+ %sum = fadd half %a, %b
+ ret half %sum
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"dx.nativelowprec", i32 1}
More information about the llvm-commits
mailing list