Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions clang/lib/CodeGen/CGHLSLRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,14 @@ 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);
if (LangOpts.NativeHalfType)
M.setModuleFlag(llvm::Module::ModFlagBehavior::Error, "dx.nativelowprec",
1);

generateGlobalCtorDtorCalls();
}
Expand Down
9 changes: 9 additions & 0 deletions clang/test/CodeGenHLSL/enable-16bit-types.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// RUN: %clang_cc1 -fnative-half-type -finclude-default-header -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=FLAG
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: For future cleanup and test organization could we move the Shader Flag tests into their own directory like the Builtins have their own directory? Not asking for this PR.

// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=NOFLAG

// NOTE: -enable-16bit-types is a DXCFlag that aliases -fnative-half-type

// FLAG-DAG: ![[NLP:.*]] = !{i32 1, !"dx.nativelowprec", i32 1}
// FLAG-DAG: !llvm.module.flags = !{{{.*}}![[NLP]]{{.*}}}

// NOFLAG-NOT: dx.nativelowprec
7 changes: 7 additions & 0 deletions llvm/lib/Target/DirectX/DXILShaderFlags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I know the frontend likely has checks to confirm SM 6.2 or greater for this flag. If the backend is dxil-pc-shadermodel6.1 what would happen in a test case like use-native-low-precision.ll? Would we just expect to not see !0 = !{i32 1, !"dx.nativelowprec", i32 1}?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The frontend is what is adding !0 = !{i32 1, !"dx.nativelowprec", i32 1}, so we wouldn't see it in the module.

If it is manually added to a module that is SM 6.1 or older, then it should have no effect on the shader flags.
Should I add a test for this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My concern was if the validator would allow the dxil if it was less than sm 6.2 and we saw nativelowprec set. The backend would be our last place to catch that and avoid the validator complaining.

If that isn't a concern then I don't think we need a test.

Copy link
Contributor Author

@Icohedron Icohedron Apr 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the validator interprets any module metadata flag named "dx.nativelowpres", so it would just be ignored if it is present in the DXIL even when the SM is lower than 6.2.

NativeLowPrec->getValue() != 0)
SCCSF.UseNativeLowPrecision = true;

ComputedShaderFlags CSF;
for (const auto &BB : *F)
for (const auto &I : BB)
Expand Down
45 changes: 45 additions & 0 deletions llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
; 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"

;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) #0 {
%sum = add i16 %a, %b
ret i16 %sum
}

; NOTE: The flag for native low precision is set for every function in the
; module regardless of whether or not the function uses low precision data
; types. This matches the behavior in DXC
;CHECK-LABEL: ; Function add_i32 : 0x00800000
define i32 @add_i32(i32 %a, i32 %b) #0 {
%sum = add i32 %a, %b
ret i32 %sum
}

;CHECK-LABEL: ; Function add_half : 0x00800020
define half @add_half(half %a, half %b) #0 {
%sum = fadd half %a, %b
ret half %sum
}

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

!llvm.module.flags = !{!0}
!0 = !{i32 1, !"dx.nativelowprec", i32 1}

; DXC: - Name: SFI0
; DXC-NEXT: Size: 8
; DXC-NOT: Flags:
; DXC: ...