https://github.com/kuilpd updated 
https://github.com/llvm/llvm-project/pull/204166

>From a6ae624e191ae5ea4592ab690edb8fe83d47d55b Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <[email protected]>
Date: Sat, 6 Jun 2026 02:49:05 +0500
Subject: [PATCH 1/5] [Driver][DirectX] Add /Qembed_debug and /Fd flags

---
 .../clang/Basic/DiagnosticDriverKinds.td      | 10 +++
 clang/include/clang/Options/Options.td        | 27 ++++---
 clang/lib/Driver/ToolChains/Clang.cpp         | 19 +++++
 clang/test/Driver/dxc_debug.hlsl              | 14 +++-
 llvm/include/llvm/MC/MCDXContainerWriter.h    |  1 +
 llvm/lib/MC/MCDXContainerWriter.cpp           | 14 ++++
 .../lib/Target/DirectX/DXContainerGlobals.cpp | 70 ++++++++-----------
 llvm/lib/Target/DirectX/DXContainerPDB.cpp    |  3 +-
 .../DirectX/DXILWriter/DXILWriterPass.cpp     | 15 ++++
 .../DirectX/ContainerData/ContainerFlags.ll   | 38 ++++++++++
 .../DebugName-default-output.test             |  1 -
 .../DebugName-user-directory.test             |  2 +-
 .../DebugName-user-specified.test             |  9 +++
 .../DirectX/ContainerData/DebugName.test      | 22 ++++++
 .../DirectX/ContainerData/PDBParts.test       |  2 +-
 .../DirectX/ContainerData/SourceInfo-Args.ll  |  3 +-
 .../ContainerData/SourceInfo-Compressed.ll    |  3 +-
 .../ContainerData/SourceInfo-Uncompressed.ll  |  3 +-
 llvm/test/CodeGen/DirectX/embed-ildb.ll       |  9 +--
 19 files changed, 201 insertions(+), 64 deletions(-)
 create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/ContainerFlags.ll
 create mode 100644 
llvm/test/CodeGen/DirectX/ContainerData/DebugName-user-specified.test
 create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/DebugName.test

diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td 
b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 8edac14f4972a..a642797e518e4 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -883,6 +883,16 @@ 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_no_debug_info_for_embed_debug
+    : Error<"must enable debug info with /Zi for /Qembed_debug">;
+def err_drv_no_debug_info_for_Fd
+    : Error<"/Fd specified, but no Debug Info was found in the shader; "
+            "please use the /Zi or /Zs switch to generate debug information "
+            "compiling this shader">;
+def warn_drv_dxc_no_output_for_debug
+    : Warning<"no output provided for debug - embedding PDB in shader "
+              "container; use /Qembed_debug to silence this warning">,
+      InGroup<DiagGroup<"default-embed-debug">>;
 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 919d46c449750..e2a14d364f457 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -9319,10 +9319,9 @@ def _SLASH_ZH_SHA1 : CLFlag<"ZH:SHA1">,
   HelpText<"Use SHA1 for file checksums in debug info">,
   Alias<gsrc_hash_EQ>, AliasArgs<["sha1"]>;
 def _SLASH_ZH_SHA_256 : CLFlag<"ZH:SHA_256">,
-  HelpText<"Use SHA256 for file checksums in debug info">,
-  Alias<gsrc_hash_EQ>, AliasArgs<["sha256"]>;
-def _SLASH_Zi : CLFlag<"Zi", [CLOption, DXCOption]>, Alias<g_Flag>,
-  HelpText<"Like /Z7">;
+                        HelpText<"Use SHA256 for file checksums in debug 
info">,
+                        Alias<gsrc_hash_EQ>,
+                        AliasArgs<["sha256"]>;
 def _SLASH_Zp : CLJoined<"Zp">,
   HelpText<"Set default maximum struct packing alignment">,
   Alias<fpack_struct_EQ>;
@@ -9666,6 +9665,18 @@ 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 dxc_Fd
+    : DXCJoinedOrSeparate<"Fd">,
+      HelpText<"Write debug information to the given file, or automatically "
+               "named file in directory when ending in '/'">;
+def dxc_Qembed_debug
+    : DXCFlag<"Qembed_debug">,
+      HelpText<"Embed PDB in shader container (must be used with /Zi)">;
+def dxc_Zi : Option<["/", "-"], "Zi", KIND_FLAG>,
+             Group<dxc_Group>,
+             Alias<g_Flag>,
+             Visibility<[CLOption, DXCOption]>,
+             HelpText<"Enable debug information">;
 def dxil_validator_version : Option<["/", "-"], "validator-version", 
KIND_SEPARATE>,
   Group<dxc_Group>, Flags<[HelpHidden]>,
   Visibility<[DXCOption, ClangOption, CC1Option]>,
@@ -9760,11 +9771,9 @@ def spirv_validator_path_EQ : Joined<["--"], 
"spirv-val-path=">, Group<dxc_Group
   HelpText<"SPIRV validator installation path">;
 def dxc_disable_validation : DXCFlag<"Vd">,
   HelpText<"Disable validation">;
-def dxc_gis : DXCFlag<"Gis">,
-  HelpText<"Enable IEEE strict mode (equivalent to -ffp-model=strict)">;
-def : Option<["/", "-"], "Qembed_debug", KIND_FLAG>, Group<dxc_Group>,
-  Flags<[Ignored]>, Visibility<[DXCOption]>,
-  HelpText<"Embed PDB in shader container (ignored)">;
+def dxc_gis
+    : DXCFlag<"Gis">,
+      HelpText<"Enable IEEE strict mode (equivalent to -ffp-model=strict)">;
 def spirv : DXCFlag<"spirv">,
   HelpText<"Generate SPIR-V code">;
 def metal : DXCFlag<"metal">, HelpText<"Generate Metal library">;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 323417e294d5a..b3b8280de3006 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3854,6 +3854,25 @@ static void RenderHLSLOptions(const Driver &D, const 
ArgList &Args,
   }
   if (Arg *A = Args.getLastArg(options::OPT_dxc_Zsb))
     A->claim(); // /Zsb is the default behavior, no need to forward it to llc.
+  bool Zi = Args.hasArg(options::OPT_g_Flag);
+  bool Qembed_debug = Args.hasArg(options::OPT_dxc_Qembed_debug);
+  Arg *Fd = Args.getLastArg(options::OPT_dxc_Fd);
+  if (Zi && !Fd && !Qembed_debug) {
+    D.Diag(diag::warn_drv_dxc_no_output_for_debug);
+    Qembed_debug = true;
+  }
+  if (Qembed_debug && !Zi)
+    D.Diag(diag::err_drv_no_debug_info_for_embed_debug);
+  if (Fd && !Zi)
+    D.Diag(diag::err_drv_no_debug_info_for_Fd);
+  if (Qembed_debug) {
+    CmdArgs.push_back("-mllvm");
+    CmdArgs.push_back("--dx-embed-debug");
+  }
+  if (Fd) {
+    CmdArgs.push_back("-mllvm");
+    CmdArgs.push_back(Args.MakeArgString("--dx-Fd=" + Twine(Fd->getValue())));
+  }
 }
 
 static void RenderOpenACCOptions(const Driver &D, const ArgList &Args,
diff --git a/clang/test/Driver/dxc_debug.hlsl b/clang/test/Driver/dxc_debug.hlsl
index 1a6c26c80750b..d90be0bb5bad2 100644
--- a/clang/test/Driver/dxc_debug.hlsl
+++ b/clang/test/Driver/dxc_debug.hlsl
@@ -1,8 +1,10 @@
 // RUN: %clang_dxc -Tlib_6_7 -### -g %s 2>&1 | FileCheck %s 
--check-prefix=CHECK,CHECK-CMD
 // 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 /Qembed_debug %s 2>&1 | FileCheck %s 
-check-prefixes=CHECK,CHECK-EMBED
 // 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 -Qembed_debug %s 2>&1 | FileCheck %s 
-check-prefixes=CHECK,CHECK-EMBED
+// RUN: %clang_dxc -Tlib_6_7 -### -Zi /Fd %t.pdb %s 2>&1 | FileCheck %s 
-check-prefixes=CHECK,CHECK-FD
+// RUN: %clang_dxc -Tlib_6_7 -### -Zi -Fd=%t.pdb %s 2>&1 | FileCheck %s 
-check-prefixes=CHECK,CHECK-FD
 // 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
@@ -15,11 +17,19 @@
 // Make sure dwarf-version is 4.
 // CHECK-DWARF-SAME: -dwarf-version=4
 // Check that the flags are converted to their llc equivalents.
+// CHECK-EMBED-SAME: --dx-embed-debug
+// CHECK-FD-SAME: --dx-Fd=
 // 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: %clang_dxc -Tlib_6_7 -### /Zi %s 2>&1 | FileCheck %s 
--check-prefix=WARN-EMBED
+// WARN-EMBED: warning: no output provided for debug - embedding PDB in shader 
container
+// RUN: not %clang_dxc -Tlib_6_7 -### /Qembed_debug %s 2>&1 | FileCheck %s 
--check-prefix=ERROR-NODBG0
+// ERROR-NODBG0: error: must enable debug info with /Zi for /Qembed_debug
+// RUN: not %clang_dxc -Tlib_6_7 -### /Fd %t.pdb %s 2>&1 | FileCheck %s 
--check-prefix=ERROR-NODBG1
+// ERROR-NODBG1: error: /Fd specified, but no Debug Info was found in the 
shader
 // 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/include/llvm/MC/MCDXContainerWriter.h 
b/llvm/include/llvm/MC/MCDXContainerWriter.h
index 8bc6d31eb25d0..1df38b6ff906b 100644
--- a/llvm/include/llvm/MC/MCDXContainerWriter.h
+++ b/llvm/include/llvm/MC/MCDXContainerWriter.h
@@ -73,6 +73,7 @@ class LLVM_ABI DXContainerObjectWriter final : public 
MCDXContainerBaseWriter,
 
 protected:
   ArrayRef<MCDXContainerPart> collectParts() override;
+  bool shouldSkipSection(StringRef SectionName, size_t SectionSize) override;
 
 public:
   DXContainerObjectWriter(std::unique_ptr<MCDXContainerTargetWriter> MOTW,
diff --git a/llvm/lib/MC/MCDXContainerWriter.cpp 
b/llvm/lib/MC/MCDXContainerWriter.cpp
index de973f2667da3..994b90fbcb66b 100644
--- a/llvm/lib/MC/MCDXContainerWriter.cpp
+++ b/llvm/lib/MC/MCDXContainerWriter.cpp
@@ -13,9 +13,13 @@
 #include "llvm/MC/MCSection.h"
 #include "llvm/MC/MCValue.h"
 #include "llvm/Support/Alignment.h"
+#include "llvm/Support/CommandLine.h"
 
 using namespace llvm;
 
+cl::opt<bool> EmbedDebug("dx-embed-debug",
+                         cl::desc("Embed PDB in shader container"));
+
 MCDXContainerTargetWriter::~MCDXContainerTargetWriter() = default;
 
 MCDXContainerBaseWriter::~MCDXContainerBaseWriter() = default;
@@ -132,6 +136,16 @@ ArrayRef<MCDXContainerPart> 
DXContainerObjectWriter::collectParts() {
   return Parts;
 }
 
+bool DXContainerObjectWriter::shouldSkipSection(StringRef SectionName,
+                                                size_t SectionSize) {
+  // Do not write ILDB part if we're not embedding it.
+  if (!EmbedDebug && SectionName == "ILDB")
+    return true;
+  if (SectionName == "SRCI")
+    return true;
+  return MCDXContainerBaseWriter::shouldSkipSection(SectionName, SectionSize);
+}
+
 uint64_t DXContainerObjectWriter::writeObject() {
   write(W.OS, getContext().getTargetTriple());
   clearParts();
diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp 
b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index 5a03b1854c9d7..16facaf13b96b 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -41,15 +41,11 @@ 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"),
-                cl::value_desc("filename"));
-static cl::opt<std::string> PdbOutputDir(
-    "dx-pdb-dir",
-    cl::desc("Specify the PDB output directory for DirectX target. The file "
-             "name is derived from the shader hash"),
-    cl::value_desc("directory"));
+cl::opt<std::string> PdbDebugPath(
+    "dx-Fd",
+    cl::desc("Write debug information to the given file, or automatically "
+             "named file in directory when ending in '/'"),
+    cl::value_desc("filename"));
 
 namespace {
 class DXContainerGlobals : public llvm::ModulePass {
@@ -148,9 +144,9 @@ void DXContainerGlobals::computeShaderHashAndDebugName(
   }
 
   Digest.update(DXILConstant->getRawDataValues());
-  MD5::MD5Result Result = Digest.final();
+  MD5::MD5Result MD5 = Digest.final();
 
-  memcpy(reinterpret_cast<void *>(&HashData.Digest), Result.data(), 16);
+  memcpy(reinterpret_cast<void *>(&HashData.Digest), MD5.data(), 16);
   if (sys::IsBigEndianHost)
     HashData.swapBytes();
   StringRef Data(reinterpret_cast<char *>(&HashData), 
sizeof(dxbc::ShaderHash));
@@ -160,47 +156,41 @@ void DXContainerGlobals::computeShaderHashAndDebugName(
   Globals.emplace_back(
       buildContainerGlobal(M, ModuleConstant, "dx.hash", "HASH"));
 
-  // Emit ILDN part in debug info mode.
-  // DXIL bitcode hash is used, which corresponds to DXC behavior with
-  // `/Zi /Qembed_debug /Zsb` flags.
   if (M.debug_compile_units().empty())
     return;
 
-  if (!PdbFileName.empty() && !PdbOutputDir.empty())
-    report_fatal_error(
-        "--dx-pdb-file and --dx-pdb-dir are mutually exclusive options");
-
   SmallString<40> DebugNameStr;
-  Digest.stringifyResult(Result, DebugNameStr);
+  Digest.stringifyResult(MD5, DebugNameStr);
   DebugNameStr += ".pdb";
+  if (!PdbDebugPath.empty()) {
+    StringRef DebugFile = PdbDebugPath.getValue();
+    SmallString<256> AbsoluteDebugName;
+    if (sys::path::is_separator(DebugFile.back())) {
+      // If /Fd was specified as a directory, put the MD5.pdb file there.
+      AbsoluteDebugName = DebugFile;
+      sys::path::append(AbsoluteDebugName, DebugNameStr);
+    } else {
+      // Otherwise, use /Fd value as a user-provided PDB file name.
+      DebugNameStr = DebugFile;
+      AbsoluteDebugName = DebugNameStr;
+    }
 
-  mcdxbc::DebugName DebugName;
-  if (PdbFileName.empty()) {
-    // Use the MD5 hash as the file name.
-    Digest.stringifyResult(Result, DebugNameStr);
-    DebugNameStr += ".pdb";
-  } else {
-    // Use user-provided PDB file name.
-    DebugNameStr = PdbFileName;
+    // Pass PDB name to DXContainerPDBPass via PDBNAME section.
+    addSection(M, Globals, AbsoluteDebugName, "dx.pdb.name",
+               PdbFileNameSectionName);
+    // Pass module hash to DXContainerPDBPass.
+    Globals.emplace_back(buildContainerGlobal(
+        M, ConstantDataArray::get(M.getContext(), ArrayRef(HashData.Digest)),
+        "dx.pdb.hash", ModuleHashSectionName));
   }
-  DebugName.setFilename(DebugNameStr);
-
-  SmallString<256> AbsoluteDebugName(PdbOutputDir);
-  sys::path::append(AbsoluteDebugName, DebugNameStr);
 
+  // Emit ILDN part in debug info mode.
+  mcdxbc::DebugName DebugName;
+  DebugName.setFilename(DebugNameStr);
   SmallString<64> ILDNData;
   raw_svector_ostream OS(ILDNData);
   DebugName.write(OS);
   addSection(M, Globals, ILDNData, "dx.ildn", "ILDN");
-
-  // TODO: Do not create PDB in embedded mode.
-  // Pass PDB name to DXContainerPDBPass via PDBNAME section.
-  addSection(M, Globals, AbsoluteDebugName, "dx.pdb.name",
-             PdbFileNameSectionName);
-  // Pass module hash to DXContainerPDBPass.
-  Globals.emplace_back(buildContainerGlobal(
-      M, ConstantDataArray::get(M.getContext(), ArrayRef(HashData.Digest)),
-      "dx.pdb.hash", ModuleHashSectionName));
 }
 
 GlobalVariable *DXContainerGlobals::buildContainerGlobal(
diff --git a/llvm/lib/Target/DirectX/DXContainerPDB.cpp 
b/llvm/lib/Target/DirectX/DXContainerPDB.cpp
index 9a0933af4c165..5d0d04a9646b4 100644
--- a/llvm/lib/Target/DirectX/DXContainerPDB.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerPDB.cpp
@@ -145,7 +145,8 @@ bool DXContainerPDB::runOnModule(Module &M) {
   // Write PDB file.
   codeview::GUID IgnoredOutGuid;
   if (Error Err = Builder.commit(DebugFileName, &IgnoredOutGuid))
-    reportFatalUsageError(std::move(Err));
+    reportFatalUsageError(
+        formatv("Couldn't write to PDB file: {0}", toString(std::move(Err))));
 
   reset();
 
diff --git a/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp 
b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp
index e78e6775403fa..9bbb87327d749 100644
--- a/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp
+++ b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp
@@ -35,6 +35,9 @@
 using namespace llvm;
 using namespace llvm::dxil;
 
+extern cl::opt<bool> EmbedDebug;
+extern cl::opt<std::string> PdbDebugPath;
+
 namespace {
 class WriteDXILPass : public llvm::ModulePass {
   raw_ostream &OS; // raw_ostream to print on
@@ -227,6 +230,18 @@ class EmbedDXILPass : public llvm::ModulePass {
     legalizeLifetimeIntrinsics(M);
 
     bool HasDebugInfo = !M.debug_compile_units().empty();
+
+    // Enable EmbedDebug if there is debug info, but it is not being written
+    // to a PDB file.
+    if (HasDebugInfo && !EmbedDebug && PdbDebugPath.empty())
+      EmbedDebug = true;
+    if (!HasDebugInfo && EmbedDebug)
+      reportFatalUsageError(
+          "Missing debug info for embedding into the container");
+    // TODO: move this check to DXContainerPDB.cpp when /Zs is implemented.
+    if (!HasDebugInfo && !PdbDebugPath.empty())
+      reportFatalUsageError("Missing debug info for writing to the PDB file");
+
     std::string ILDBData;
     if (HasDebugInfo) {
       // Write DXIL with debug info to ILDB part.
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/ContainerFlags.ll 
b/llvm/test/CodeGen/DirectX/ContainerData/ContainerFlags.ll
new file mode 100644
index 0000000000000..36eb5b0b1b8e3
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/ContainerFlags.ll
@@ -0,0 +1,38 @@
+;; Check that --dx-embed-debug is enabled by default when debug info is present
+; RUN: llc %S/Inputs/SourceInfo.ll --filetype=obj -o %t.cso
+; RUN: obj2yaml %t.cso | FileCheck %s --check-prefix=DEFAULT-EMBED
+; DEFAULT-EMBED: Parts:
+; DEFAULT-EMBED:   - Name:            ILDB
+; DEFAULT-EMBED:   - Name:            ILDN
+
+;; Check that debug info is not embedded if only the PDB ouput is specified
+; RUN: llc %S/Inputs/SourceInfo.ll --filetype=obj --dx-Fd=%t.pdb -o %t.cso
+; RUN: obj2yaml %t.cso | FileCheck %s --check-prefix=NO-EMBED
+; NO-EMBED: Parts:
+; NO-EMBED-NOT:   - Name:            ILDB
+; NO-EMBED:       - Name:            ILDN
+
+;; Check that debug info is both embedded and output to the PDB
+;; if both options are specified
+; RUN: llc %S/Inputs/SourceInfo.ll --filetype=obj --dx-embed-debug 
--dx-Fd=%t.pdb -o %t.cso
+; RUN: obj2yaml %t.cso | FileCheck %s --check-prefix=EMBED
+; EMBED: Parts:
+; EMBED:   - Name:            ILDB
+; EMBED:   - Name:            ILDN
+; RUN: llvm-pdbutil pdb2yaml --dxcontainer %t.pdb | FileCheck %s 
--check-prefix=PDB
+; Check that PDB file contains only debug-info relevant parts.
+; PDB:     Parts:
+; PDB-DAG:   - Name:            ILDB
+; PDB-DAG:   - Name:            ILDN
+
+;; Check errors when trying to output debug info with no debug info present
+; RUN: not llc %s --filetype=obj --dx-embed-debug -o %t.cso 2>&1 | FileCheck 
%s --check-prefix=ERROR-NODBG
+; ERROR-NODBG: Missing debug info for embedding into the container
+; RUN: not llc %s --filetype=obj --dx-Fd=%t.pdb -o %t.cso 2>&1 | FileCheck %s 
--check-prefix=ERROR-NODBG-PDB
+; ERROR-NODBG-PDB: Missing debug info for writing to the PDB file
+
+target triple = "dxil-unknown-shadermodel6.5-library"
+
+define i32 @foo(i32 %a) {
+  ret i32 %a
+}
diff --git 
a/llvm/test/CodeGen/DirectX/ContainerData/DebugName-default-output.test 
b/llvm/test/CodeGen/DirectX/ContainerData/DebugName-default-output.test
index 3914a3250df7d..abaee2ac5b3b3 100644
--- a/llvm/test/CodeGen/DirectX/ContainerData/DebugName-default-output.test
+++ b/llvm/test/CodeGen/DirectX/ContainerData/DebugName-default-output.test
@@ -3,7 +3,6 @@ RUN: llvm-objcopy --dump-section=DXIL=%t0.bc %t.dxbc
 RUN: %md5sum %t0.bc >%t0.bc.md5
 RUN: obj2yaml %t.dxbc >%t.yaml
 RUN: cat %t.yaml %t0.bc.md5 | FileCheck %s
-RUN: %python %S/Inputs/check_pdb_exists.py "" "%t0.bc.md5"
 
 CHECK-NOT:   - Name:            PDBN
 CHECK-NOT:   - Name:            PDBH
diff --git 
a/llvm/test/CodeGen/DirectX/ContainerData/DebugName-user-directory.test 
b/llvm/test/CodeGen/DirectX/ContainerData/DebugName-user-directory.test
index 3a6fb6c0476f2..f380fe6458b8f 100644
--- a/llvm/test/CodeGen/DirectX/ContainerData/DebugName-user-directory.test
+++ b/llvm/test/CodeGen/DirectX/ContainerData/DebugName-user-directory.test
@@ -1,5 +1,5 @@
 RUN: rm -rf %t && mkdir %t
-RUN: llc %S/Inputs/SourceInfo.ll --filetype=obj -o %t.dxbc --dx-pdb-dir=%t
+RUN: llc %S/Inputs/SourceInfo.ll --filetype=obj -o %t.dxbc --dx-Fd=%t/
 RUN: llvm-objcopy --dump-section=DXIL=%t0.bc %t.dxbc
 RUN: %md5sum %t0.bc >%t0.bc.md5
 RUN: obj2yaml %t.dxbc >%t.yaml
diff --git 
a/llvm/test/CodeGen/DirectX/ContainerData/DebugName-user-specified.test 
b/llvm/test/CodeGen/DirectX/ContainerData/DebugName-user-specified.test
new file mode 100644
index 0000000000000..a2a8a3d1d79e9
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/DebugName-user-specified.test
@@ -0,0 +1,9 @@
+RUN: rm -rf %t && mkdir %t
+RUN: llc %S/Inputs/SourceInfo.ll --filetype=obj -o - --dx-Fd=%t/ofile.pdb | 
obj2yaml | FileCheck %s
+RUN: test -f %t/ofile.pdb
+
+CHECK:       - Name:            ILDN
+CHECK:         DebugName:
+CHECK-NEXT:      Flags:           0
+CHECK-NEXT:      NameLength:      {{.*}}
+CHECK-NEXT:      DebugName:       {{.*[/\]+}}ofile.pdb
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/DebugName.test 
b/llvm/test/CodeGen/DirectX/ContainerData/DebugName.test
new file mode 100644
index 0000000000000..d2462aec17e6b
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/DebugName.test
@@ -0,0 +1,22 @@
+# Check that debug name and hashed are passed to DXContainerPDBPass, but
+# not emitted into output file (checked with --implicit-check-not arguments).
+RUN: opt %S/Inputs/SourceInfo.ll -dxil-embed -dxil-globals --dx-Fd=%t.pdb -S 
-o - \
+RUN:   | FileCheck %s --check-prefix=BC
+BC:          @dx.pdb.name
+BC:          @dx.pdb.hash
+
+# Check that ILDN debug name is calculated from DXIL by default.
+RUN: llc %S/Inputs/SourceInfo.ll --filetype=obj -o %t.dxbc
+RUN: llvm-objcopy --dump-section=DXIL=%t0.bc %t.dxbc
+RUN: %md5sum %t0.bc >%t0.bc.md5
+RUN: obj2yaml %t.dxbc >%t.yaml
+RUN: cat %t.yaml %t0.bc.md5 | FileCheck %s --implicit-check-not PDBN 
--implicit-check-not PDBH
+
+CHECK:       - Name:            ILDN
+CHECK-NEXT:    Size:            44
+CHECK-NEXT:    DebugName:
+CHECK-NEXT:      Flags:           0
+CHECK-NEXT:      NameLength:      36
+CHECK-NEXT:      DebugName:       [[MD5:[0-9a-f]+]].pdb
+CHECK:       ...
+CHECK-NEXT:  [[MD5]]
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/PDBParts.test 
b/llvm/test/CodeGen/DirectX/ContainerData/PDBParts.test
index 8fc7f5adb4e9c..9964bb87585ab 100644
--- a/llvm/test/CodeGen/DirectX/ContainerData/PDBParts.test
+++ b/llvm/test/CodeGen/DirectX/ContainerData/PDBParts.test
@@ -1,5 +1,5 @@
 RUN: rm -rf %t && mkdir %t
-RUN: llc %S/Inputs/SourceInfo.ll --filetype=obj -o %t.dxbc 
--dx-pdb-file=%t/parts.pdb
+RUN: llc %S/Inputs/SourceInfo.ll --filetype=obj -o %t.dxbc --dx-Fd=%t/parts.pdb
 RUN: llvm-pdbutil pdb2yaml --dxcontainer %t/parts.pdb | FileCheck %s
 
 # Check that debug-related container parts are emitted into companion PDB file.
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Args.ll 
b/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Args.ll
index 9b22812e212df..299136e3ac1de 100644
--- a/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Args.ll
+++ b/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Args.ll
@@ -1,4 +1,5 @@
-; RUN: llc %S/Inputs/SourceInfo.ll --filetype=obj -o - | obj2yaml | FileCheck 
%s --check-prefix=DXC
+; RUN: llc %S/Inputs/SourceInfo.ll --filetype=obj --dx-Fd=%t.pdb -o /dev/null
+; RUN: llvm-pdbutil pdb2yaml --dxcontainer %t.pdb | FileCheck %s 
--check-prefix=DXC
 
 ; DXC:      - Name:            SRCI
 ; DXC:        SourceInfo:
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Compressed.ll 
b/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Compressed.ll
index 1d7e39fb77ff2..5ee7255788c8c 100644
--- a/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Compressed.ll
+++ b/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Compressed.ll
@@ -1,5 +1,6 @@
 ; RUN: opt %S/Inputs/SourceInfo.ll -dxil-embed -dxil-globals -S -o - | 
FileCheck %s
-; RUN: llc %S/Inputs/SourceInfo.ll --filetype=obj -o - | obj2yaml | FileCheck 
%s --check-prefix=DXC
+; RUN: llc %S/Inputs/SourceInfo.ll --filetype=obj --dx-Fd=%t.pdb -o /dev/null
+; RUN: llvm-pdbutil pdb2yaml --dxcontainer %t.pdb | FileCheck %s 
--check-prefix=DXC
 ; REQUIRES: zlib
 
 ; CHECK: @dx.srci = private constant [348 x i8] c"{{.*}}", section "SRCI", 
align 4
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Uncompressed.ll 
b/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Uncompressed.ll
index df42386f1c418..6ced1580812b1 100644
--- a/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Uncompressed.ll
+++ b/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Uncompressed.ll
@@ -1,5 +1,6 @@
 ; RUN: opt %S/Inputs/SourceInfo.ll -compress-srci=none -dxil-embed 
-dxil-globals -S -o - | FileCheck %s
-; RUN: llc %S/Inputs/SourceInfo.ll -compress-srci=none --filetype=obj -o - | 
obj2yaml | FileCheck %s --check-prefix=DXC
+; RUN: llc %S/Inputs/SourceInfo.ll -compress-srci=none --filetype=obj 
--dx-Fd=%t.pdb -o /dev/null
+; RUN: llvm-pdbutil pdb2yaml --dxcontainer %t.pdb | FileCheck %s 
--check-prefix=DXC
 
 ; CHECK: @dx.srci = private constant [416 x i8] c"{{.*}}", section "SRCI", 
align 4
 
diff --git a/llvm/test/CodeGen/DirectX/embed-ildb.ll 
b/llvm/test/CodeGen/DirectX/embed-ildb.ll
index 5f1b17e0e1e56..84bdad2b39e08 100644
--- a/llvm/test/CodeGen/DirectX/embed-ildb.ll
+++ b/llvm/test/CodeGen/DirectX/embed-ildb.ll
@@ -1,6 +1,6 @@
 ; RUN: rm -f %t.pdb
 ; RUN: opt %s -dxil-embed -dxil-globals -S -o - | FileCheck %s
-; RUN: llc %s --filetype=obj -o %t.bc --dx-pdb-file=%t.pdb
+; RUN: llc %s --filetype=obj --dx-embed-debug -o %t.bc --dx-Fd=%t.pdb
 ; RUN: obj2yaml %t.bc | FileCheck %s --check-prefix=YAML
 ; RUN: llvm-objcopy --dump-section=ILDB=%t.ildb %t.bc
 ; RUN: llvm-objcopy --dump-section=DXIL=%t.dxil %t.bc
@@ -40,11 +40,11 @@ define i32 @add(i32 %a, i32 %b) {
 !7 = !{!"hlsl.hlsl"}
 !8 = !{!"-T", !"lib_6_5", !"-g", !"hlsl.hlsl"}
 
-; Check that DXIL, ILDB and SRCI parts are emitted as a GV and used by the 
compiler.
+
+; Check that DXIL and ILDB parts are emitted as a GV and used by the compiler.
 
 ; CHECK: @dx.ildb = private constant [[BC_TYPE:\[[0-9]+ x i8\]]] 
c"BC\C0\DE{{[^"]+}}", section "ILDB", align 4
 ; CHECK: @dx.dxil = private constant [[BC_TYPE:\[[0-9]+ x i8\]]] 
c"BC\C0\DE{{[^"]+}}", section "DXIL", align 4
-; CHECK: @dx.srci = private constant {{\[[0-9]+ x i8\]}}
 ; CHECK: @llvm.compiler.used = appending global {{\[[0-9]+ x ptr\]}} [ptr 
@dx.ildb, ptr @dx.dxil
 
 ; This is using regex matches on some sizes, offsets and fields. These are all
@@ -89,9 +89,6 @@ define i32 @add(i32 %a, i32 %b) {
 ; YAML-NEXT:       DXILSize:        [[#DXILSIZE - 24]]
 ; YAML-NEXT:       DXIL:            [ 0x42, 0x43, 0xC0, 0xDE,
 
-; Check that despite dx.source is stripped from DXIL, SRCI is still emitted:
-; YAML:   - Name:            SRCI
-
 ; Check that ILDB has the debug info, and DXIL does not:
 
 ; ILDB-DIS: define i32 @add(i32 %a, i32 %b)

>From 616f7719ee59a6093a72358266b46c83c1d3b04a Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <[email protected]>
Date: Wed, 17 Jun 2026 04:27:11 +0500
Subject: [PATCH 2/5] Use c_str for formatv

---
 llvm/lib/Target/DirectX/DXContainerPDB.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXContainerPDB.cpp 
b/llvm/lib/Target/DirectX/DXContainerPDB.cpp
index 5d0d04a9646b4..824bc001dd0d3 100644
--- a/llvm/lib/Target/DirectX/DXContainerPDB.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerPDB.cpp
@@ -145,8 +145,8 @@ bool DXContainerPDB::runOnModule(Module &M) {
   // Write PDB file.
   codeview::GUID IgnoredOutGuid;
   if (Error Err = Builder.commit(DebugFileName, &IgnoredOutGuid))
-    reportFatalUsageError(
-        formatv("Couldn't write to PDB file: {0}", toString(std::move(Err))));
+    reportFatalUsageError(formatv("Couldn't write to PDB file: {0}",
+                                  toString(std::move(Err)).c_str()));
 
   reset();
 

>From de2ad3562e0f5a50b0fd2a790e66137af171d6e7 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <[email protected]>
Date: Wed, 17 Jun 2026 21:19:13 +0500
Subject: [PATCH 3/5] Use Twine in error message

---
 llvm/lib/Target/DirectX/DXContainerPDB.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXContainerPDB.cpp 
b/llvm/lib/Target/DirectX/DXContainerPDB.cpp
index 824bc001dd0d3..49fb9f4b290fb 100644
--- a/llvm/lib/Target/DirectX/DXContainerPDB.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerPDB.cpp
@@ -145,8 +145,8 @@ bool DXContainerPDB::runOnModule(Module &M) {
   // Write PDB file.
   codeview::GUID IgnoredOutGuid;
   if (Error Err = Builder.commit(DebugFileName, &IgnoredOutGuid))
-    reportFatalUsageError(formatv("Couldn't write to PDB file: {0}",
-                                  toString(std::move(Err)).c_str()));
+    reportFatalUsageError("Couldn't write to PDB file: " +
+                          Twine(toString(std::move(Err))));
 
   reset();
 

>From 8179e4a95c0f14357e812369dcdf15b9e4a17186 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <[email protected]>
Date: Fri, 19 Jun 2026 15:42:05 +0500
Subject: [PATCH 4/5] Adjust Options.td

---
 clang/include/clang/Options/Options.td | 31 +++++++++++---------------
 1 file changed, 13 insertions(+), 18 deletions(-)

diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index e2a14d364f457..ceb430029aba1 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -9319,9 +9319,10 @@ def _SLASH_ZH_SHA1 : CLFlag<"ZH:SHA1">,
   HelpText<"Use SHA1 for file checksums in debug info">,
   Alias<gsrc_hash_EQ>, AliasArgs<["sha1"]>;
 def _SLASH_ZH_SHA_256 : CLFlag<"ZH:SHA_256">,
-                        HelpText<"Use SHA256 for file checksums in debug 
info">,
-                        Alias<gsrc_hash_EQ>,
-                        AliasArgs<["sha256"]>;
+  HelpText<"Use SHA256 for file checksums in debug info">,
+  Alias<gsrc_hash_EQ>, AliasArgs<["sha256"]>;
+def _SLASH_Zi : CLFlag<"Zi", [CLOption, DXCOption]>, Alias<g_Flag>,
+  HelpText<"Enable debug information">;
 def _SLASH_Zp : CLJoined<"Zp">,
   HelpText<"Set default maximum struct packing alignment">,
   Alias<fpack_struct_EQ>;
@@ -9661,22 +9662,14 @@ 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 dxc_Zsb : DXCFlag<"Zsb">,
-              HelpText<"Compute Shader Hash considering only output binary">;
 def dxc_Fd
     : DXCJoinedOrSeparate<"Fd">,
       HelpText<"Write debug information to the given file, or automatically "
                "named file in directory when ending in '/'">;
-def dxc_Qembed_debug
-    : DXCFlag<"Qembed_debug">,
-      HelpText<"Embed PDB in shader container (must be used with /Zi)">;
-def dxc_Zi : Option<["/", "-"], "Zi", KIND_FLAG>,
-             Group<dxc_Group>,
-             Alias<g_Flag>,
-             Visibility<[CLOption, DXCOption]>,
-             HelpText<"Enable debug information">;
+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]>,
@@ -9771,9 +9764,11 @@ def spirv_validator_path_EQ : Joined<["--"], 
"spirv-val-path=">, Group<dxc_Group
   HelpText<"SPIRV validator installation path">;
 def dxc_disable_validation : DXCFlag<"Vd">,
   HelpText<"Disable validation">;
-def dxc_gis
-    : DXCFlag<"Gis">,
-      HelpText<"Enable IEEE strict mode (equivalent to -ffp-model=strict)">;
+def dxc_gis : DXCFlag<"Gis">,
+  HelpText<"Enable IEEE strict mode (equivalent to -ffp-model=strict)">;
+def dxc_Qembed_debug
+    : DXCFlag<"Qembed_debug">,
+      HelpText<"Embed PDB in shader container (must be used with /Zi)">;
 def spirv : DXCFlag<"spirv">,
   HelpText<"Generate SPIR-V code">;
 def metal : DXCFlag<"metal">, HelpText<"Generate Metal library">;

>From a5dc61c04e2661580a8cb9195ef394299b624ef7 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <[email protected]>
Date: Fri, 19 Jun 2026 16:08:21 +0500
Subject: [PATCH 5/5] Rename local Zi to HasDebug

---
 clang/lib/Driver/ToolChains/Clang.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index b3b8280de3006..1a4f4fcec2c9a 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3854,16 +3854,16 @@ static void RenderHLSLOptions(const Driver &D, const 
ArgList &Args,
   }
   if (Arg *A = Args.getLastArg(options::OPT_dxc_Zsb))
     A->claim(); // /Zsb is the default behavior, no need to forward it to llc.
-  bool Zi = Args.hasArg(options::OPT_g_Flag);
+  bool HasDebug = Args.hasArg(options::OPT_g_Flag);
   bool Qembed_debug = Args.hasArg(options::OPT_dxc_Qembed_debug);
   Arg *Fd = Args.getLastArg(options::OPT_dxc_Fd);
-  if (Zi && !Fd && !Qembed_debug) {
+  if (HasDebug && !Fd && !Qembed_debug) {
     D.Diag(diag::warn_drv_dxc_no_output_for_debug);
     Qembed_debug = true;
   }
-  if (Qembed_debug && !Zi)
+  if (Qembed_debug && !HasDebug)
     D.Diag(diag::err_drv_no_debug_info_for_embed_debug);
-  if (Fd && !Zi)
+  if (Fd && !HasDebug)
     D.Diag(diag::err_drv_no_debug_info_for_Fd);
   if (Qembed_debug) {
     CmdArgs.push_back("-mllvm");

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to