From 2039fa7a08f488f0029e31d0402447da0b142634 Mon Sep 17 00:00:00 2001 From: Icohedron Date: Mon, 12 May 2025 20:58:36 +0000 Subject: [PATCH 1/8] Set shader feature flags MinimumPrecision and NativeLowPrecision --- llvm/lib/Target/DirectX/DXILShaderFlags.cpp | 8 ++++++++ .../DirectX/ShaderFlags/low-precision.ll | 20 ++++++++++++++++--- .../ShaderFlags/use-native-low-precision-0.ll | 18 +++++++++++++---- .../ShaderFlags/use-native-low-precision-1.ll | 19 +++++++++++++++--- 4 files changed, 55 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index b50a9b5d6051c..36f909ffa6ef5 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -296,6 +296,14 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM, if (NumUAVs > 8) CombinedSFMask.Max64UAVs = true; + // Set the Shader Feature Info flags related to low-precision datatypes + if (CombinedSFMask.LowPrecisionPresent) { + if (CombinedSFMask.UseNativeLowPrecision) + CombinedSFMask.NativeLowPrecision = true; + else + CombinedSFMask.MinimumPrecision = true; + } + CombinedSFMask.UAVsAtEveryStage = hasUAVsAtEveryStage(DRM, MMDI); } diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/low-precision.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/low-precision.ll index 561e09bb1e9dc..bccc14d2b38cb 100644 --- a/llvm/test/CodeGen/DirectX/ShaderFlags/low-precision.ll +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/low-precision.ll @@ -1,4 +1,10 @@ ; 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" @@ -6,25 +12,33 @@ target triple = "dxil-pc-shadermodel6.7-library" ;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: ; ;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: ... diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-0.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-0.ll index c537a01482f39..e4d55d3d89013 100644 --- a/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-0.ll +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-0.ll @@ -1,7 +1,9 @@ ; 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" @@ -9,6 +11,7 @@ target triple = "dxil-pc-shadermodel6.7-library" ;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 @@ -16,22 +19,29 @@ 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) { +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: ... diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll index 07c4b9064d666..6ee592de087a6 100644 --- a/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll @@ -1,4 +1,9 @@ ; 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" @@ -6,6 +11,7 @@ target triple = "dxil-pc-shadermodel6.7-library" ;CHECK-NEXT: ; Shader Flags Value: 0x00800020 ;CHECK-NEXT: ; ;CHECK-NEXT: ; Note: shader requires additional functionality: +;CHECK-NEXT: ; Use native low precision ;CHECK-NEXT: ; Note: extra DXIL module flags: ;CHECK-NEXT: ; Low-precision data types ;CHECK-NEXT: ; Use native low precision @@ -13,7 +19,7 @@ target triple = "dxil-pc-shadermodel6.7-library" ;CHECK-NEXT: ; Shader Flags for Module Functions ;CHECK-LABEL: ; Function add_i16 : 0x00800020 -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 } @@ -22,16 +28,23 @@ define i16 @add_i16(i16 %a, i16 %b) { ; 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) { +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) { +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: ... From aa824aca6fe81c2a3528edd41a8db932087aa667 Mon Sep 17 00:00:00 2001 From: Icohedron Date: Tue, 13 May 2025 17:40:29 +0000 Subject: [PATCH 2/8] Refactor flags related to low precision data types and combine the NativeLowPrecision module and feature flags --- .../BinaryFormat/DXContainerConstants.def | 3 +- llvm/lib/Target/DirectX/DXILShaderFlags.cpp | 35 +++++++++---------- llvm/lib/Target/DirectX/DXILShaderFlags.h | 1 + .../ShaderFlags/use-native-low-precision-1.ll | 9 +++-- 4 files changed, 23 insertions(+), 25 deletions(-) diff --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def index 1645018aebedb..ed259524570a1 100644 --- a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def +++ b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def @@ -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, 23, NativeLowPrecision, "Use native low precision") 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") @@ -117,7 +117,6 @@ 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( 8, AllResourcesBound, "All resources bound for the duration of shader execution") -DXIL_MODULE_FLAG(23, UseNativeLowPrecision, "Use native low precision") DXIL_MODULE_FLAG(33, ResMayNotAlias, "Any UAV may not alias any other UAV") #undef DXIL_MODULE_FLAG diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index 36f909ffa6ef5..dd9cd8849525f 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -142,6 +142,13 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF, } } + if (CSF.LowPrecisionPresent) { + if (NativeLowPrecisionAvailable) + CSF.NativeLowPrecision = true; + else + CSF.MinimumPrecision = true; + } + if (!CSF.Int64Ops) CSF.Int64Ops = I.getType()->isIntegerTy(64); @@ -206,14 +213,21 @@ 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( M.getModuleFlag("dx.resmayalias"))) if (RMA->getValue() != 0) CanSetResMayNotAlias = false; + // Set UseNativeLowPrecision using the dx.nativelowprec module flag set by + // the command line option -enable-16bit-types + if (auto *NativeLowPrec = mdconst::extract_or_null( + M.getModuleFlag("dx.nativelowprec"))) + if (MMDI.ShaderModelVersion >= VersionTuple(6, 2) && + NativeLowPrec->getValue() != 0) + NativeLowPrecisionAvailable = true; + CallGraph CG(M); // Compute Shader Flags Mask for all functions using post-order visit of SCC @@ -243,13 +257,6 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM, 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( - 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) @@ -296,14 +303,6 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM, if (NumUAVs > 8) CombinedSFMask.Max64UAVs = true; - // Set the Shader Feature Info flags related to low-precision datatypes - if (CombinedSFMask.LowPrecisionPresent) { - if (CombinedSFMask.UseNativeLowPrecision) - CombinedSFMask.NativeLowPrecision = true; - else - CombinedSFMask.MinimumPrecision = true; - } - CombinedSFMask.UAVsAtEveryStage = hasUAVsAtEveryStage(DRM, MMDI); } diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.h b/llvm/lib/Target/DirectX/DXILShaderFlags.h index 0e0bd0036349e..5fa5cf48c16f8 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.h +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.h @@ -92,6 +92,7 @@ struct ModuleShaderFlags { private: bool CanSetResMayNotAlias; + bool NativeLowPrecisionAvailable; /// 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 diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll index 6ee592de087a6..5cc15be48f4a9 100644 --- a/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll @@ -14,7 +14,6 @@ target triple = "dxil-pc-shadermodel6.7-library" ;CHECK-NEXT: ; Use native low precision ;CHECK-NEXT: ; Note: extra DXIL module flags: ;CHECK-NEXT: ; Low-precision data types -;CHECK-NEXT: ; Use native low precision ;CHECK-NEXT: ; ;CHECK-NEXT: ; Shader Flags for Module Functions @@ -24,10 +23,10 @@ define i16 @add_i16(i16 %a, i16 %b) "hlsl.export" { 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 +; NOTE: In DXC, 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). However, this will not be the case for Clang +;CHECK-LABEL: ; Function add_i32 : 0x00000000 define i32 @add_i32(i32 %a, i32 %b) "hlsl.export" { %sum = add i32 %a, %b ret i32 %sum From 4cb533b474a7e6f7dc5fd207561a6e2cfb3b4b64 Mon Sep 17 00:00:00 2001 From: Icohedron Date: Tue, 13 May 2025 17:51:22 +0000 Subject: [PATCH 3/8] Fix comment about the -enable-16bit-types flag --- llvm/lib/Target/DirectX/DXILShaderFlags.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index dd9cd8849525f..11f3a1e4a8c18 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -220,8 +220,9 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM, if (RMA->getValue() != 0) CanSetResMayNotAlias = false; - // Set UseNativeLowPrecision using the dx.nativelowprec module flag set by - // the command line option -enable-16bit-types + // NativeLowPrecision 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 if (auto *NativeLowPrec = mdconst::extract_or_null( M.getModuleFlag("dx.nativelowprec"))) if (MMDI.ShaderModelVersion >= VersionTuple(6, 2) && From 610f4357502b9edb29ea69ba37e80039374b3f30 Mon Sep 17 00:00:00 2001 From: Icohedron Date: Tue, 13 May 2025 18:45:26 +0000 Subject: [PATCH 4/8] Set default value of NativeLowPrecisionAvailable to false --- llvm/lib/Target/DirectX/DXILShaderFlags.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index 11f3a1e4a8c18..c359e3036b6cd 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -223,6 +223,7 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM, // NativeLowPrecision 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 + NativeLowPrecisionAvailable = false; if (auto *NativeLowPrec = mdconst::extract_or_null( M.getModuleFlag("dx.nativelowprec"))) if (MMDI.ShaderModelVersion >= VersionTuple(6, 2) && From bc8396d1865f2cc8400c30368f91bf1038190616 Mon Sep 17 00:00:00 2001 From: Icohedron Date: Tue, 13 May 2025 21:44:47 +0000 Subject: [PATCH 5/8] Reintroduce Native Low Precision module flag, and refactor module flags --- .../BinaryFormat/DXContainerConstants.def | 3 ++- llvm/lib/Target/DirectX/DXILShaderFlags.cpp | 24 ++++++++++++------- llvm/lib/Target/DirectX/DXILShaderFlags.h | 6 +++-- .../ShaderFlags/res-may-not-alias-sm6.7.ll | 8 +++---- .../ShaderFlags/use-native-low-precision-1.ll | 10 ++++---- 5 files changed, 29 insertions(+), 22 deletions(-) diff --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def index ed259524570a1..a86719018b36c 100644 --- a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def +++ b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def @@ -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, 23, 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") @@ -117,6 +117,7 @@ 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( 8, AllResourcesBound, "All resources bound for the duration of shader execution") +DXIL_MODULE_FLAG(23, NativeLowPrecisionMode, "Use native low precision") DXIL_MODULE_FLAG(33, ResMayNotAlias, "Any UAV may not alias any other UAV") #undef DXIL_MODULE_FLAG diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index c359e3036b6cd..b6436119d878e 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -143,7 +143,7 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF, } if (CSF.LowPrecisionPresent) { - if (NativeLowPrecisionAvailable) + if (NativeLowPrecisionMode) CSF.NativeLowPrecision = true; else CSF.MinimumPrecision = true; @@ -220,15 +220,15 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM, if (RMA->getValue() != 0) CanSetResMayNotAlias = false; - // NativeLowPrecision can only be set when the command line option + // 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 - NativeLowPrecisionAvailable = false; + NativeLowPrecisionMode = false; if (auto *NativeLowPrec = mdconst::extract_or_null( M.getModuleFlag("dx.nativelowprec"))) if (MMDI.ShaderModelVersion >= VersionTuple(6, 2) && NativeLowPrec->getValue() != 0) - NativeLowPrecisionAvailable = true; + NativeLowPrecisionMode = true; CallGraph CG(M); @@ -254,11 +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(); - ComputedShaderFlags CSF; for (const auto &BB : *F) for (const auto &I : BB) @@ -295,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; + // Set the Max64UAVs flag if the number of UAVs is > 8 uint32_t NumUAVs = 0; for (auto &UAV : DRM.uavs()) diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.h b/llvm/lib/Target/DirectX/DXILShaderFlags.h index 5fa5cf48c16f8..31d7748305afd 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.h +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.h @@ -91,8 +91,10 @@ struct ModuleShaderFlags { const ComputedShaderFlags &getCombinedFlags() const { return CombinedSFMask; } private: - bool CanSetResMayNotAlias; - bool NativeLowPrecisionAvailable; + // 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 diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.7.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.7.ll index 934319557a11f..fc6560e321b4b 100644 --- a/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.7.ll +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.7.ll @@ -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" @@ -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) @@ -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) diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll index 5cc15be48f4a9..bdccabfb2f219 100644 --- a/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll @@ -11,28 +11,26 @@ target triple = "dxil-pc-shadermodel6.7-library" ;CHECK-NEXT: ; Shader Flags Value: 0x00800020 ;CHECK-NEXT: ; ;CHECK-NEXT: ; Note: shader requires additional functionality: -;CHECK-NEXT: ; Use native low precision +;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: ; ;CHECK-NEXT: ; Shader Flags for Module Functions -;CHECK-LABEL: ; Function add_i16 : 0x00800020 +;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: In DXC, 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). However, this will not be the case for Clang ;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 +;CHECK-LABEL: ; Function add_half : 0x00000020 define half @add_half(half %a, half %b) "hlsl.export" { %sum = fadd half %a, %b ret half %sum From 70d48492e9f036d64c5b3beacd9311799c251228 Mon Sep 17 00:00:00 2001 From: Icohedron Date: Tue, 13 May 2025 21:53:14 +0000 Subject: [PATCH 6/8] Revise descriptions of flags related to low-precision data types --- llvm/include/llvm/BinaryFormat/DXContainerConstants.def | 6 +++--- llvm/test/CodeGen/DirectX/ShaderFlags/low-precision.ll | 2 +- .../DirectX/ShaderFlags/use-native-low-precision-0.ll | 4 ++-- .../DirectX/ShaderFlags/use-native-low-precision-1.ll | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def index a86719018b36c..81d2c54b6e07c 100644 --- a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def +++ b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def @@ -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, "Native low precision data types") +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") @@ -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, NativeLowPrecisionMode, "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 diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/low-precision.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/low-precision.ll index bccc14d2b38cb..5ecac3980d044 100644 --- a/llvm/test/CodeGen/DirectX/ShaderFlags/low-precision.ll +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/low-precision.ll @@ -14,7 +14,7 @@ target triple = "dxil-pc-shadermodel6.7-library" ;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 diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-0.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-0.ll index e4d55d3d89013..2e68fe375a42c 100644 --- a/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-0.ll +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-0.ll @@ -13,8 +13,8 @@ target triple = "dxil-pc-shadermodel6.7-library" ;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 diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll index bdccabfb2f219..cb3b486cebce5 100644 --- a/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll @@ -11,10 +11,10 @@ target triple = "dxil-pc-shadermodel6.7-library" ;CHECK-NEXT: ; Shader Flags Value: 0x00800020 ;CHECK-NEXT: ; ;CHECK-NEXT: ; Note: shader requires additional functionality: -;CHECK-NEXT: ; Native low precision data types +;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 From fe5d588d6f415be68885dca750cb010dcd80e681 Mon Sep 17 00:00:00 2001 From: "Deric C." Date: Tue, 13 May 2025 16:47:47 -0700 Subject: [PATCH 7/8] Assign bool value of NativeLowPrecisionMode directly Co-authored-by: Justin Bogner --- llvm/lib/Target/DirectX/DXILShaderFlags.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index b6436119d878e..64252b5605377 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -226,9 +226,8 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM, NativeLowPrecisionMode = false; if (auto *NativeLowPrec = mdconst::extract_or_null( M.getModuleFlag("dx.nativelowprec"))) - if (MMDI.ShaderModelVersion >= VersionTuple(6, 2) && - NativeLowPrec->getValue() != 0) - NativeLowPrecisionMode = true; + if (MMDI.ShaderModelVersion >= VersionTuple(6, 2)) + NativeLowPrecisionMode = NativeLowPrec->getValue().getBoolValue(); CallGraph CG(M); From c0dbfbb5111d80bcbcb2e3bdab84d4fb8d602ef1 Mon Sep 17 00:00:00 2001 From: Icohedron Date: Wed, 14 May 2025 00:05:12 +0000 Subject: [PATCH 8/8] Rename bools set by module flags to be consistent --- llvm/lib/Target/DirectX/DXILShaderFlags.cpp | 15 +++++++-------- llvm/lib/Target/DirectX/DXILShaderFlags.h | 4 ++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index 64252b5605377..8bdaf68e18e70 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -143,7 +143,7 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF, } if (CSF.LowPrecisionPresent) { - if (NativeLowPrecisionMode) + if (CanSetNativeLowPrecisionMode) CSF.NativeLowPrecision = true; else CSF.MinimumPrecision = true; @@ -214,20 +214,19 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM, CanSetResMayNotAlias = MMDI.DXILVersion >= VersionTuple(1, 7); // 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( + // flag to 1, thereby disabling the ability to set the ResMayNotAlias flag + if (auto *ResMayAlias = mdconst::extract_or_null( M.getModuleFlag("dx.resmayalias"))) - if (RMA->getValue() != 0) - CanSetResMayNotAlias = false; + CanSetResMayNotAlias = !ResMayAlias->getValue().getBoolValue(); // 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; + CanSetNativeLowPrecisionMode = false; if (auto *NativeLowPrec = mdconst::extract_or_null( M.getModuleFlag("dx.nativelowprec"))) if (MMDI.ShaderModelVersion >= VersionTuple(6, 2)) - NativeLowPrecisionMode = NativeLowPrec->getValue().getBoolValue(); + CanSetNativeLowPrecisionMode = NativeLowPrec->getValue().getBoolValue(); CallGraph CG(M); @@ -298,7 +297,7 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM, // 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; + CombinedSFMask.NativeLowPrecisionMode = CanSetNativeLowPrecisionMode; // Set the Max64UAVs flag if the number of UAVs is > 8 uint32_t NumUAVs = 0; diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.h b/llvm/lib/Target/DirectX/DXILShaderFlags.h index 31d7748305afd..c4eef4e708cfd 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.h +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.h @@ -92,8 +92,8 @@ struct ModuleShaderFlags { private: // Booleans set by module flags - bool CanSetResMayNotAlias; // dx.resmayalias - bool NativeLowPrecisionMode; // dx.nativelowprec + bool CanSetResMayNotAlias; // dx.resmayalias + bool CanSetNativeLowPrecisionMode; // 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