diff --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def index 1645018aebedb..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, "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") @@ -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 diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index b50a9b5d6051c..8bdaf68e18e70 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 (CanSetNativeLowPrecisionMode) + CSF.NativeLowPrecision = true; + else + CSF.MinimumPrecision = true; + } + if (!CSF.Int64Ops) CSF.Int64Ops = I.getType()->isIntegerTy(64); @@ -206,13 +213,20 @@ 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. - if (auto *RMA = mdconst::extract_or_null( + // The command line option -res-may-alias will set the dx.resmayalias module + // 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 + CanSetNativeLowPrecisionMode = false; + if (auto *NativeLowPrec = mdconst::extract_or_null( + M.getModuleFlag("dx.nativelowprec"))) + if (MMDI.ShaderModelVersion >= VersionTuple(6, 2)) + CanSetNativeLowPrecisionMode = NativeLowPrec->getValue().getBoolValue(); CallGraph CG(M); @@ -238,18 +252,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( - 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) @@ -286,6 +288,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 = CanSetNativeLowPrecisionMode; + // 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 0e0bd0036349e..c4eef4e708cfd 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.h +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.h @@ -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 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 /// module-level and function-level flags diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/low-precision.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/low-precision.ll index 561e09bb1e9dc..5ecac3980d044 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: ; 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: ... 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-0.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-0.ll index c537a01482f39..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 @@ -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,29 +11,37 @@ 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 +;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: ... 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..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 @@ -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,32 +11,37 @@ 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: ; 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: ...