Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
6 changes: 3 additions & 3 deletions llvm/include/llvm/BinaryFormat/DXContainerConstants.def
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ SHADER_FEATURE_FLAG(14, 19, WaveOps, "Wave level operations")
SHADER_FEATURE_FLAG(15, 20, Int64Ops, "64-Bit integer")
SHADER_FEATURE_FLAG(16, 21, ViewID, "View Instancing")
SHADER_FEATURE_FLAG(17, 22, Barycentrics, "Barycentrics")
SHADER_FEATURE_FLAG(18, -1, NativeLowPrecision, "Use native low precision")
SHADER_FEATURE_FLAG(18, -1, NativeLowPrecision, "Native low-precision data types")
SHADER_FEATURE_FLAG(19, 24, ShadingRate, "Shading Rate")
SHADER_FEATURE_FLAG(20, 25, Raytracing_Tier_1_1, "Raytracing tier 1.1 features")
SHADER_FEATURE_FLAG(21, 26, SamplerFeedback, "Sampler feedback")
Expand Down Expand Up @@ -115,9 +115,9 @@ DXIL_MODULE_FLAG( 0, DisableOptimizations, "Disable shader optimizations")
DXIL_MODULE_FLAG( 1, DisableMathRefactoring, "Disable math refactoring")
DXIL_MODULE_FLAG( 3, ForceEarlyDepthStencil, "Force early depth-stencil test")
DXIL_MODULE_FLAG( 4, EnableRawAndStructuredBuffers, "Raw and structured buffers")
DXIL_MODULE_FLAG( 5, LowPrecisionPresent, "Low-precision data types")
DXIL_MODULE_FLAG( 5, LowPrecisionPresent, "Low-precision data types present")
DXIL_MODULE_FLAG( 8, AllResourcesBound, "All resources bound for the duration of shader execution")
DXIL_MODULE_FLAG(23, UseNativeLowPrecision, "Use native low precision")
DXIL_MODULE_FLAG(23, NativeLowPrecisionMode, "Enable native low-precision data types")
DXIL_MODULE_FLAG(33, ResMayNotAlias, "Any UAV may not alias any other UAV")

#undef DXIL_MODULE_FLAG
Expand Down
45 changes: 30 additions & 15 deletions llvm/lib/Target/DirectX/DXILShaderFlags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,13 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF,
}
}

if (CSF.LowPrecisionPresent) {
if (NativeLowPrecisionMode)
CSF.NativeLowPrecision = true;
else
CSF.MinimumPrecision = true;
}

if (!CSF.Int64Ops)
CSF.Int64Ops = I.getType()->isIntegerTy(64);

Expand Down Expand Up @@ -206,14 +213,23 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
const ModuleMetadataInfo &MMDI) {

CanSetResMayNotAlias = MMDI.DXILVersion >= VersionTuple(1, 7);

// Check if -res-may-alias was provided on the command line.
// The command line option will set the dx.resmayalias module flag to 1.
// The command line option -res-may-alias will set the dx.resmayalias module
// flag to 1 and disable the ability to set the ResMayNotAlias flag
if (auto *RMA = mdconst::extract_or_null<ConstantInt>(
M.getModuleFlag("dx.resmayalias")))
if (RMA->getValue() != 0)
CanSetResMayNotAlias = false;

// NativeLowPrecisionMode can only be set when the command line option
// -enable-16bit-types is provided. This is indicated by the dx.nativelowprec
// module flag being set
NativeLowPrecisionMode = false;
if (auto *NativeLowPrec = mdconst::extract_or_null<ConstantInt>(
M.getModuleFlag("dx.nativelowprec")))
if (MMDI.ShaderModelVersion >= VersionTuple(6, 2) &&
NativeLowPrec->getValue() != 0)
NativeLowPrecisionMode = true;

CallGraph CG(M);

// Compute Shader Flags Mask for all functions using post-order visit of SCC
Expand All @@ -238,18 +254,6 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
continue;
}

// Set ResMayNotAlias to true if DXIL validator version < 1.8 and there
// are UAVs present globally.
if (CanSetResMayNotAlias && MMDI.ValidatorVersion < VersionTuple(1, 8))
SCCSF.ResMayNotAlias = !DRM.uavs().empty();

// Set UseNativeLowPrecision using dx.nativelowprec module metadata
if (auto *NativeLowPrec = mdconst::extract_or_null<ConstantInt>(
M.getModuleFlag("dx.nativelowprec")))
if (MMDI.ShaderModelVersion >= VersionTuple(6, 2) &&
NativeLowPrec->getValue() != 0)
SCCSF.UseNativeLowPrecision = true;

ComputedShaderFlags CSF;
for (const auto &BB : *F)
for (const auto &I : BB)
Expand Down Expand Up @@ -286,6 +290,17 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
*(EntryFunProps.Entry), "Inconsistent optnone attribute "));
}

// Set ResMayNotAlias to true if DXIL validator version < 1.8 and there
// are UAVs present globally.
if (CanSetResMayNotAlias && MMDI.ValidatorVersion < VersionTuple(1, 8))
CombinedSFMask.ResMayNotAlias = !DRM.uavs().empty();

// Set the module flag that enables native low-precision execution mode. This
// is needed even if the module does not use 16-bit types because a
// corresponding debug module may include 16-bit types, and tools that use the
// debug module may expect it to have the same flags as the original
CombinedSFMask.NativeLowPrecisionMode = NativeLowPrecisionMode;
Copy link
Contributor Author

@Icohedron Icohedron May 13, 2025

Choose a reason for hiding this comment

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

Setting the module flags via CombinedSFMask instead of SCCSF will make the module flags be set on the module only and not the functions themselves. This is consistent with the way the DisableOptimizations flag is currently set in Clang.
However, it does not match the behavior of DXC (see DxilShaderFlags.cpp) which sets every flag at the function level.
I don't think it matters though? The final DXIL module flags and shader feature flags work out to be the same in the end.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, this feels like an implementation detail - I don't think there's any way to see a difference in the end.


// Set the Max64UAVs flag if the number of UAVs is > 8
uint32_t NumUAVs = 0;
for (auto &UAV : DRM.uavs())
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/Target/DirectX/DXILShaderFlags.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,10 @@ struct ModuleShaderFlags {
const ComputedShaderFlags &getCombinedFlags() const { return CombinedSFMask; }

private:
bool CanSetResMayNotAlias;
// Booleans set by module flags
bool CanSetResMayNotAlias; // dx.resmayalias
bool NativeLowPrecisionMode; // dx.nativelowprec

/// Map of Function-Shader Flag Mask pairs representing properties of each of
/// the functions in the module. Shader Flags of each function represent both
/// module-level and function-level flags
Expand Down
22 changes: 18 additions & 4 deletions llvm/test/CodeGen/DirectX/ShaderFlags/low-precision.ll
Original file line number Diff line number Diff line change
@@ -1,30 +1,44 @@
; 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

; Check that when the dx.nativelowprec module flag is not specified, the
; module-level shader flag UseNativeLowPrecision is not set, and the
; MinimumPrecision feature flag is set due to the presence of half and i16
; without native low precision.

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

;CHECK: ; Combined Shader Flags for Module
;CHECK-NEXT: ; Shader Flags Value: 0x00000020
;CHECK-NEXT: ;
;CHECK-NEXT: ; Note: shader requires additional functionality:
;CHECK-NEXT: ; Minimum-precision data types
;CHECK-NEXT: ; Note: extra DXIL module flags:
;CHECK-NEXT: ; Low-precision data types
;CHECK-NEXT: ; Low-precision data types present
;CHECK-NEXT: ;
;CHECK-NEXT: ; Shader Flags for Module Functions

;CHECK-LABEL: ; Function add_i16 : 0x00000020
define i16 @add_i16(i16 %a, i16 %b) {
define i16 @add_i16(i16 %a, i16 %b) "hlsl.export" {
%sum = add i16 %a, %b
ret i16 %sum
}

;CHECK-LABEL: ; Function add_i32 : 0x00000000
define i32 @add_i32(i32 %a, i32 %b) {
define i32 @add_i32(i32 %a, i32 %b) "hlsl.export" {
%sum = add i32 %a, %b
ret i32 %sum
}

;CHECK-LABEL: ; Function add_half : 0x00000020
define half @add_half(half %a, half %b) {
define half @add_half(half %a, half %b) "hlsl.export" {
%sum = fadd half %a, %b
ret half %sum
}

; DXC: - Name: SFI0
; DXC-NEXT: Size: 8
; DXC-NEXT: Flags:
; DXC: MinimumPrecision: true
; DXC: NativeLowPrecision: false
; DXC: ...
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

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

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

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

; CHECK: Function loadSRV : 0x200000010
; CHECK: Function loadSRV : 0x00000010
define float @loadSRV() #0 {
%res = tail call target("dx.RawBuffer", float, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,47 @@
; 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

; Check that when the dx.nativelowprec module flag is set to 0, the module-level
; shader flag UseNativeLowPrecision is not set
; shader flag UseNativeLowPrecision is not set, and the MinimumPrecision feature
; flag is set due to the presence of half and i16 without native low precision.

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

;CHECK: ; Combined Shader Flags for Module
;CHECK-NEXT: ; Shader Flags Value: 0x00000020
;CHECK-NEXT: ;
;CHECK-NEXT: ; Note: shader requires additional functionality:
;CHECK-NEXT: ; Minimum-precision data types
;CHECK-NEXT: ; Note: extra DXIL module flags:
;CHECK-NEXT: ; Low-precision data types
;CHECK-NOT: ; Native 16bit types enabled
;CHECK-NEXT: ; Low-precision data types present
;CHECK-NOT: ; Enable native low-precision data types
;CHECK-NEXT: ;
;CHECK-NEXT: ; Shader Flags for Module Functions

;CHECK-LABEL: ; Function add_i16 : 0x00000020
define i16 @add_i16(i16 %a, i16 %b) {
define i16 @add_i16(i16 %a, i16 %b) "hlsl.export" {
%sum = add i16 %a, %b
ret i16 %sum
}

;CHECK-LABEL: ; Function add_i32 : 0x00000000
define i32 @add_i32(i32 %a, i32 %b) {
define i32 @add_i32(i32 %a, i32 %b) "hlsl.export" {
%sum = add i32 %a, %b
ret i32 %sum
}

;CHECK-LABEL: ; Function add_half : 0x00000020
define half @add_half(half %a, half %b) {
define half @add_half(half %a, half %b) "hlsl.export" {
%sum = fadd half %a, %b
ret half %sum
}

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

; DXC: - Name: SFI0
; DXC-NEXT: Size: 8
; DXC-NEXT: Flags:
; DXC: MinimumPrecision: true
; DXC: NativeLowPrecision: false
; DXC: ...
32 changes: 21 additions & 11 deletions llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll
Original file line number Diff line number Diff line change
@@ -1,37 +1,47 @@
; 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

; Check that when the dx.nativelowprec module flag is set to 1, the module-level
; shader flag UseNativeLowPrecision is set, and the NativeLowPrecision feature
; flag is set

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: ; Native low-precision data types
;CHECK-NEXT: ; Note: extra DXIL module flags:
;CHECK-NEXT: ; Low-precision data types
;CHECK-NEXT: ; Use native low precision
;CHECK-NEXT: ; Low-precision data types present
;CHECK-NEXT: ; Enable native low-precision data types
;CHECK-NEXT: ;
;CHECK-NEXT: ; Shader Flags for Module Functions

;CHECK-LABEL: ; Function add_i16 : 0x00800020
define i16 @add_i16(i16 %a, i16 %b) {
;CHECK-LABEL: ; Function add_i16 : 0x00000020
define i16 @add_i16(i16 %a, i16 %b) "hlsl.export" {
%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) {
;CHECK-LABEL: ; Function add_i32 : 0x00000000
define i32 @add_i32(i32 %a, i32 %b) "hlsl.export" {
%sum = add i32 %a, %b
ret i32 %sum
}

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

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

; DXC: - Name: SFI0
; DXC-NEXT: Size: 8
; DXC-NEXT: Flags:
; DXC: MinimumPrecision: false
; DXC: NativeLowPrecision: true
; DXC: ...
Loading