[llvm] [DirectX] Set shader feature flags MinimumPrecision and NativeLowPrecision, and refactor the logic for setting low-precision-related flags (PR #139623)

Deric C. via llvm-commits llvm-commits at lists.llvm.org
Tue May 13 16:47:57 PDT 2025


https://github.com/Icohedron updated https://github.com/llvm/llvm-project/pull/139623

>From 2039fa7a08f488f0029e31d0402447da0b142634 Mon Sep 17 00:00:00 2001
From: Icohedron <cheung.deric at gmail.com>
Date: Mon, 12 May 2025 20:58:36 +0000
Subject: [PATCH 1/7] 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 <cheung.deric at gmail.com>
Date: Tue, 13 May 2025 17:40:29 +0000
Subject: [PATCH 2/7] 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<ConstantInt>(
           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<ConstantInt>(
+          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<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)
@@ -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 <cheung.deric at gmail.com>
Date: Tue, 13 May 2025 17:51:22 +0000
Subject: [PATCH 3/7] 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<ConstantInt>(
           M.getModuleFlag("dx.nativelowprec")))
     if (MMDI.ShaderModelVersion >= VersionTuple(6, 2) &&

>From 610f4357502b9edb29ea69ba37e80039374b3f30 Mon Sep 17 00:00:00 2001
From: Icohedron <cheung.deric at gmail.com>
Date: Tue, 13 May 2025 18:45:26 +0000
Subject: [PATCH 4/7] 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<ConstantInt>(
           M.getModuleFlag("dx.nativelowprec")))
     if (MMDI.ShaderModelVersion >= VersionTuple(6, 2) &&

>From bc8396d1865f2cc8400c30368f91bf1038190616 Mon Sep 17 00:00:00 2001
From: Icohedron <cheung.deric at gmail.com>
Date: Tue, 13 May 2025 21:44:47 +0000
Subject: [PATCH 5/7] 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<ConstantInt>(
           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 <cheung.deric at gmail.com>
Date: Tue, 13 May 2025 21:53:14 +0000
Subject: [PATCH 6/7] 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." <cheung.deric at gmail.com>
Date: Tue, 13 May 2025 16:47:47 -0700
Subject: [PATCH 7/7] Assign bool value of NativeLowPrecisionMode directly

Co-authored-by: Justin Bogner <mail at justinbogner.com>
---
 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<ConstantInt>(
           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);
 



More information about the llvm-commits mailing list