[clang] [llvm] [Driver][DirectX] Add `-Zss` and `-Zsb` flags (PR #203960)
Ilia Kuklin via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 17 07:15:51 PDT 2026
https://github.com/kuilpd updated https://github.com/llvm/llvm-project/pull/203960
>From 93fea845381549590b58db341f898d9f7526e0ca Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 21 May 2026 21:30:09 +0500
Subject: [PATCH 1/2] [Driver][DirectX] Add -Zss flag
---
clang/include/clang/Options/Options.td | 2 ++
clang/lib/Driver/ToolChains/Clang.cpp | 5 ++++
.../lib/Target/DirectX/DXContainerGlobals.cpp | 20 +++++++++++--
.../DirectX/ContainerData/DebugShaderHash.ll | 30 +++++++++++++++----
4 files changed, 48 insertions(+), 9 deletions(-)
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index fdc288b27017d..8b10d0b97075f 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -9662,6 +9662,8 @@ def dxc_Fc : DXCJoinedOrSeparate<"Fc">,
HelpText<"Output assembly listing file">;
def dxc_Frs : DXCJoinedOrSeparate<"Frs">,
HelpText<"Output additional root signature object file">;
+def dxc_Zss : DXCFlag<"Zss">,
+ HelpText<"Compute Shader Hash considering source information">;
def dxil_validator_version : Option<["/", "-"], "validator-version", KIND_SEPARATE>,
Group<dxc_Group>, Flags<[HelpHidden]>,
Visibility<[DXCOption, ClangOption, CC1Option]>,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index dcab2e41391bb..5c40f20728554 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3838,6 +3838,11 @@ static void RenderHLSLOptions(const ArgList &Args, ArgStringList &CmdArgs,
if (!Args.hasArg(options::OPT_dxc_no_stdinc) &&
!Args.hasArg(options::OPT_nostdinc))
CmdArgs.push_back("-finclude-default-header");
+
+ if (Args.hasArg(options::OPT_dxc_Zss)) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-dx-Zss");
+ }
}
static void RenderOpenACCOptions(const Driver &D, const ArgList &Args,
diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index 49a02d82bd108..63ec5a551f69c 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -39,6 +39,8 @@ using namespace llvm;
using namespace llvm::dxil;
using namespace llvm::mcdxbc;
+static cl::opt<bool> ShaderHashDependsOnSource(
+ "dx-Zss", cl::desc("Compute Shader Hash considering source information"));
static cl::opt<std::string>
PdbFileName("dx-pdb-file",
cl::desc("Specify the PDB output file path for DirectX target"),
@@ -129,10 +131,22 @@ void DXContainerGlobals::addSection(Module &M,
void DXContainerGlobals::computeShaderHashAndDebugName(
Module &M, SmallVector<GlobalValue *> &Globals) {
- // TODO: Add -Zss flag to enable/disable calculating shader hash from ILDB.
- auto *DXILConstant =
- cast<ConstantDataArray>(M.getNamedGlobal("dx.dxil")->getInitializer());
+ ConstantDataArray *DXILConstant;
MD5 Digest;
+ dxbc::ShaderHash HashData = {0, {0}};
+
+ if (ShaderHashDependsOnSource) {
+ if (auto *ILDB = M.getNamedGlobal("dx.ildb")) {
+ DXILConstant = cast<ConstantDataArray>(ILDB->getInitializer());
+ HashData.Flags = static_cast<uint32_t>(dxbc::HashFlags::IncludesSource);
+ } else {
+ reportFatalUsageError("/Zss requires debug info (/Zi or /Zs)");
+ }
+ } else {
+ DXILConstant =
+ cast<ConstantDataArray>(M.getNamedGlobal("dx.dxil")->getInitializer());
+ }
+
Digest.update(DXILConstant->getRawDataValues());
MD5::MD5Result Result = Digest.final();
dxbc::ShaderHash HashData = {0, {0}};
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/DebugShaderHash.ll b/llvm/test/CodeGen/DirectX/ContainerData/DebugShaderHash.ll
index c0febd5bf758d..1675367252121 100644
--- a/llvm/test/CodeGen/DirectX/ContainerData/DebugShaderHash.ll
+++ b/llvm/test/CodeGen/DirectX/ContainerData/DebugShaderHash.ll
@@ -1,5 +1,10 @@
; RUN: opt %s -dxil-embed -dxil-globals -S -o - | FileCheck %s
-; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
+
+; RUN: llc %s --filetype=obj -o - | obj2yaml -o %t0.yaml
+; RUN: llc -dx-Zss %s --filetype=obj -o - | obj2yaml -o %t1.yaml
+;; Put the YAML files together to compare matched hashes.
+; RUN: cat %t0.yaml %t1.yaml | FileCheck %s --check-prefix=YAML
+
target triple = "dxil-unknown-shadermodel6.5-library"
; CHECK: @dx.hash = private constant [20 x i8] c"\00\00\00\00{{.*}}", section "HASH", align 4
@@ -18,8 +23,21 @@ define i32 @add(i32 %a, i32 %b) {
!3 = !{i32 7, !"Dwarf Version", i32 2}
!4 = !{i32 2, !"Debug Info Version", i32 3}
-; DXC: - Name: HASH
-; DXC: Size: 20
-; DXC: Hash:
-; DXC: IncludesSource: false
-; DXC: Digest: [
+;; Check that the default DXContainer has a hash that doesn't include the source
+; YAML: --- !dxcontainer
+; YAML: - Name: HASH
+; YAML: Size: 20
+; YAML: Hash:
+; YAML: IncludesSource: false
+; YAML: Digest: [ [[HASH:.+]]
+; YAML: ...
+
+;; Check that the -Zss DXContainer has a hash that includes the source and
+;; is not the same as the hash from the other one.
+; YAML: --- !dxcontainer
+; YAML: - Name: HASH
+; YAML: Size: 20
+; YAML: Hash:
+; YAML: IncludesSource: true
+; YAML: Digest: [
+; YAML-NOT: Digest: [ [[HASH]]
>From 3283162cd7646c77a90a44712d31a310942c4dfe Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Fri, 22 May 2026 20:58:40 +0500
Subject: [PATCH 2/2] [Driver][DirectX] Add -Zsb flag and fix/add flag tests
---
clang/include/clang/Basic/DiagnosticDriverKinds.td | 2 ++
clang/include/clang/Options/Options.td | 2 ++
clang/lib/Driver/ToolChains/Clang.cpp | 10 +++++++---
clang/test/Driver/dxc_debug.hlsl | 7 +++++++
llvm/lib/Target/DirectX/DXContainerGlobals.cpp | 1 -
.../CodeGen/DirectX/ContainerData/DebugShaderHash.ll | 2 +-
llvm/test/CodeGen/DirectX/ContainerData/ShaderHash.ll | 6 ++++++
7 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 6aba0622be193..8edac14f4972a 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -881,6 +881,8 @@ def err_drv_dxc_missing_target_profile : Error<
"target profile option (-T) is missing">;
def err_drv_dxc_Fre_requires_Fo_metal
: Error<"-Fre option requires -Fo option when targeting Metal">;
+def err_drv_dxc_invalid_shader_hash
+ : Error<"cannot specify both /Zss and /Zsb">;
def err_drv_hlsl_unsupported_target : Error<
"HLSL code generation is unsupported for target '%0'">;
def err_drv_hlsl_bad_shader_required_in_target : Error<
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 8b10d0b97075f..919d46c449750 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -9664,6 +9664,8 @@ def dxc_Frs : DXCJoinedOrSeparate<"Frs">,
HelpText<"Output additional root signature object file">;
def dxc_Zss : DXCFlag<"Zss">,
HelpText<"Compute Shader Hash considering source information">;
+def dxc_Zsb : DXCFlag<"Zsb">,
+ HelpText<"Compute Shader Hash considering only output binary">;
def dxil_validator_version : Option<["/", "-"], "validator-version", KIND_SEPARATE>,
Group<dxc_Group>, Flags<[HelpHidden]>,
Visibility<[DXCOption, ClangOption, CC1Option]>,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 5c40f20728554..3f35000cfe455 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3808,8 +3808,8 @@ static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs,
}
}
-static void RenderHLSLOptions(const ArgList &Args, ArgStringList &CmdArgs,
- types::ID InputType) {
+static void RenderHLSLOptions(const Driver &D, const ArgList &Args,
+ ArgStringList &CmdArgs, types::ID InputType) {
const unsigned ForwardedArguments[] = {
options::OPT_hlsl_all_resources_bound,
options::OPT_dxil_validator_version,
@@ -3840,9 +3840,13 @@ static void RenderHLSLOptions(const ArgList &Args, ArgStringList &CmdArgs,
CmdArgs.push_back("-finclude-default-header");
if (Args.hasArg(options::OPT_dxc_Zss)) {
+ if (Args.hasArg(options::OPT_dxc_Zsb))
+ D.Diag(diag::err_drv_dxc_invalid_shader_hash);
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("-dx-Zss");
}
+ if (Arg *A = Args.getLastArg(options::OPT_dxc_Zsb))
+ A->claim(); // /Zsb is the default behavior, no need to forward it to llc.
}
static void RenderOpenACCOptions(const Driver &D, const ArgList &Args,
@@ -7210,7 +7214,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
RenderOpenCLOptions(Args, CmdArgs, InputType);
// Forward hlsl options to -cc1
- RenderHLSLOptions(Args, CmdArgs, InputType);
+ RenderHLSLOptions(D, Args, CmdArgs, InputType);
// Forward OpenACC options to -cc1
RenderOpenACCOptions(D, Args, CmdArgs, InputType);
diff --git a/clang/test/Driver/dxc_debug.hlsl b/clang/test/Driver/dxc_debug.hlsl
index d250e95a0bfae..1a6c26c80750b 100644
--- a/clang/test/Driver/dxc_debug.hlsl
+++ b/clang/test/Driver/dxc_debug.hlsl
@@ -3,6 +3,7 @@
// RUN: %clang_dxc -Tlib_6_7 -### /Zi /Qembed_debug %s 2>&1 | FileCheck %s
// RUN: %clang_dxc -Tlib_6_7 -### -Zi %s 2>&1 | FileCheck %s
// RUN: %clang_dxc -Tlib_6_7 -### -Zi -Qembed_debug %s 2>&1 | FileCheck %s
+// RUN: %clang_dxc -Tlib_6_7 -### -Zi -Zss %s 2>&1 | FileCheck %s --check-prefix=CHECK,CHECK-ZSS
// RUN: %clang_dxc -Tlib_6_7 -### -Zi -gcodeview %s 2>&1 | FileCheck %s -check-prefixes=CHECK,CHECK-CV
// RUN: %clang_dxc -Tlib_6_7 -### -Zi -gdwarf %s 2>&1 | FileCheck %s -check-prefixes=CHECK,CHECK-DWARF
// RUN: %clang_dxc -Tlib_6_7 -### -gcodeview -Zi %s 2>&1 | FileCheck %s -check-prefixes=CHECK,CHECK-CV
@@ -13,6 +14,12 @@
// CHECK-SAME: "-debug-info-kind=constructor"
// Make sure dwarf-version is 4.
// CHECK-DWARF-SAME: -dwarf-version=4
+// Check that the flags are converted to their llc equivalents.
+// CHECK-ZSS-SAME: -dx-Zss
// Make sure dxc command line arguments are passed to clang invocation.
// CHECK-SAME: -fdx-record-command-line
// CHECK-CMD-SAME: --driver-mode=dxc -T lib_6_7 -### -g {{.*}}dxc_debug.hlsl
+
+// Check errors and warnings
+// RUN: not %clang_dxc -Tlib_6_7 -### -Zss -Zsb %s 2>&1 | FileCheck %s --check-prefix=CHECK-ZSS-ZSB
+// CHECK-ZSS-ZSB: cannot specify both /Zss and /Zsb
diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index 63ec5a551f69c..5a03b1854c9d7 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -149,7 +149,6 @@ void DXContainerGlobals::computeShaderHashAndDebugName(
Digest.update(DXILConstant->getRawDataValues());
MD5::MD5Result Result = Digest.final();
- dxbc::ShaderHash HashData = {0, {0}};
memcpy(reinterpret_cast<void *>(&HashData.Digest), Result.data(), 16);
if (sys::IsBigEndianHost)
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/DebugShaderHash.ll b/llvm/test/CodeGen/DirectX/ContainerData/DebugShaderHash.ll
index 1675367252121..ae4fb427887c6 100644
--- a/llvm/test/CodeGen/DirectX/ContainerData/DebugShaderHash.ll
+++ b/llvm/test/CodeGen/DirectX/ContainerData/DebugShaderHash.ll
@@ -40,4 +40,4 @@ define i32 @add(i32 %a, i32 %b) {
; YAML: Hash:
; YAML: IncludesSource: true
; YAML: Digest: [
-; YAML-NOT: Digest: [ [[HASH]]
+; YAML-NOT: [[HASH]]
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/ShaderHash.ll b/llvm/test/CodeGen/DirectX/ContainerData/ShaderHash.ll
index 088a7b0071663..49539b384f5df 100644
--- a/llvm/test/CodeGen/DirectX/ContainerData/ShaderHash.ll
+++ b/llvm/test/CodeGen/DirectX/ContainerData/ShaderHash.ll
@@ -1,5 +1,11 @@
; RUN: opt %s -dxil-embed -dxil-globals -S -o - | FileCheck %s
; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
+
+;; Check that llc reports an error when attempting to calculate shader hash with sources
+;; when no debug info is present.
+; RUN: not llc -dx-Zss %s --filetype=obj -o - 2>&1 | FileCheck %s --check-prefix=ZSS
+; ZSS: /Zss requires debug info
+
target triple = "dxil-unknown-shadermodel6.5-library"
; CHECK: @dx.hash = private constant [20 x i8] c"\00\00\00\00{{.*}}", section "HASH", align 4
More information about the cfe-commits
mailing list