From e8d72961496569646022c1dc16d5105cc691b0fc Mon Sep 17 00:00:00 2001 From: Ilia Kuklin Date: Thu, 28 May 2026 02:52:33 +0500 Subject: [PATCH] [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 | 8 ++ llvm/include/llvm/MC/MCDXContainerWriter.h | 1 + llvm/lib/MC/MCDXContainerWriter.cpp | 12 ++ .../lib/Target/DirectX/DXContainerGlobals.cpp | 69 +++++----- .../DirectX/DXILWriter/DXILWriterPass.cpp | 121 ++++++++++-------- .../Target/DirectX/DirectXTargetMachine.cpp | 3 + .../DirectX/ContainerData/ContainerFlags.ll | 34 +++++ .../DebugName-default-output.test | 17 --- .../DebugName-user-directory.test | 4 +- .../DebugName-user-specified.test | 2 +- .../DirectX/ContainerData/DebugName.test | 3 +- .../DirectX/ContainerData/PDBParts.test | 2 +- llvm/test/CodeGen/DirectX/embed-ildb.ll | 2 +- 16 files changed, 213 insertions(+), 121 deletions(-) create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/ContainerFlags.ll delete mode 100644 llvm/test/CodeGen/DirectX/ContainerData/DebugName-default-output.test diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 863711cb9909..bb6346ece2e4 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -834,6 +834,16 @@ def err_drv_dxc_missing_target_profile : Error< "target profile option (-T) is missing">; 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>; 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 7230a1952e33..4bc6d161188e 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, AliasArgs<["sha1"]>; def _SLASH_ZH_SHA_256 : CLFlag<"ZH:SHA_256">, - HelpText<"Use SHA256 for file checksums in debug info">, - Alias, AliasArgs<["sha256"]>; -def _SLASH_Zi : CLFlag<"Zi", [CLOption, DXCOption]>, Alias, - HelpText<"Like /Z7">; + HelpText<"Use SHA256 for file checksums in debug info">, + Alias, + AliasArgs<["sha256"]>; def _SLASH_Zp : CLJoined<"Zp">, HelpText<"Set default maximum struct packing alignment">, Alias; @@ -9652,6 +9651,18 @@ def dxc_Fc : DXCJoinedOrSeparate<"Fc">, HelpText<"Output assembly listing file">; def dxc_Frs : DXCJoinedOrSeparate<"Frs">, HelpText<"Output additional root signature object file">; +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, + Alias, + Visibility<[CLOption, DXCOption]>, + HelpText<"Enable debug information">; def dxc_Zss : DXCFlag<"Zss">, HelpText<"Compute Shader Hash considering source information">; def dxc_Zsb : DXCFlag<"Zsb">, @@ -9747,11 +9758,9 @@ def dxc_validator_path_EQ : Joined<["--"], "dxv-path=">, Group, HelpText<"DXIL 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, - 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 3b664ce7f343..4a263a1b3af7 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3777,6 +3777,25 @@ static void RenderHLSLOptions(const Driver &D, const ArgList &Args, CmdArgs.push_back("-mllvm"); CmdArgs.push_back("--dx-source-in-debug-module"); } + 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 cec8bf3c8ab7..f3ac9250bbc3 100644 --- a/clang/test/Driver/dxc_debug.hlsl +++ b/clang/test/Driver/dxc_debug.hlsl @@ -16,3 +16,11 @@ // 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 -S -O3 + +// 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 diff --git a/llvm/include/llvm/MC/MCDXContainerWriter.h b/llvm/include/llvm/MC/MCDXContainerWriter.h index fc12e7654849..6fb7056d376a 100644 --- a/llvm/include/llvm/MC/MCDXContainerWriter.h +++ b/llvm/include/llvm/MC/MCDXContainerWriter.h @@ -73,6 +73,7 @@ class DXContainerObjectWriter final : public MCDXContainerBaseWriter, protected: ArrayRef getParts() override; + bool shouldSkipSection(StringRef SectionName, size_t SectionSize) override; public: DXContainerObjectWriter(std::unique_ptr MOTW, diff --git a/llvm/lib/MC/MCDXContainerWriter.cpp b/llvm/lib/MC/MCDXContainerWriter.cpp index 5c3ade7281d1..bd978c55b2b2 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 EmbedDebug("dx-embed-debug", + cl::desc("Embed PDB in shader container")); + MCDXContainerTargetWriter::~MCDXContainerTargetWriter() = default; MCDXContainerBaseWriter::~MCDXContainerBaseWriter() = default; @@ -132,6 +136,14 @@ ArrayRef DXContainerObjectWriter::getParts() { 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; + return MCDXContainerBaseWriter::shouldSkipSection(SectionName, SectionSize); +} + uint64_t DXContainerObjectWriter::writeObject() { // TODO write only necessary sections. write(W.OS, getContext().getTargetTriple()); diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp index 44a59cbae6a8..fffb86345991 100644 --- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp +++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp @@ -39,15 +39,12 @@ using namespace llvm; using namespace llvm::dxil; using namespace llvm::mcdxbc; -static cl::opt - PdbFileName("dx-pdb-file", - cl::desc("Specify the PDB output file path for DirectX target"), - cl::value_desc("filename")); -static cl::opt 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")); +extern llvm::cl::opt EmbedDebug; +cl::opt 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")); static cl::opt ShaderHashDependsOnSource( "dx-Zss", cl::desc("Compute Shader Hash considering source information")); extern cl::opt SourceInDebugModule; @@ -149,9 +146,9 @@ void DXContainerGlobals::computeShaderHashAndDebugName( } Digest.update(DXILConstant->getRawDataValues()); - MD5::MD5Result Result = Digest.final(); + MD5::MD5Result MD5 = Digest.final(); - memcpy(reinterpret_cast(&HashData.Digest), Result.data(), 16); + memcpy(reinterpret_cast(&HashData.Digest), MD5.data(), 16); if (sys::IsBigEndianHost) HashData.swapBytes(); StringRef Data(reinterpret_cast(&HashData), sizeof(dxbc::ShaderHash)); @@ -168,38 +165,40 @@ void DXContainerGlobals::computeShaderHashAndDebugName( if (!MMI.SourceInfo) return; - if (!PdbFileName.empty() && !PdbOutputDir.empty()) - report_fatal_error( - "--dx-pdb-file and --dx-pdb-dir are mutually exclusive options"); + if (!EmbedDebug && PdbDebugPath.empty()) + return; SmallString<40> DebugNameStr; - mcdxbc::DebugName DebugName; - if (PdbFileName.empty()) { - // TODO Add an option to compute hash based on ILDB. - Digest.stringifyResult(Result, DebugNameStr); - DebugNameStr += ".pdb"; - } else { - // Use user-provided PDB file name. - DebugNameStr = PdbFileName; - } - DebugName.setFilename(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; + } - SmallString<256> AbsoluteDebugName(PdbOutputDir); - sys::path::append(AbsoluteDebugName, DebugNameStr); + // 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)); + } + 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/DXILWriter/DXILWriterPass.cpp b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp index 9b6c549a223c..893a68e40a0e 100644 --- a/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp +++ b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp @@ -36,6 +36,8 @@ using namespace llvm; using namespace llvm::dxil; +extern cl::opt EmbedDebug; +extern cl::opt PdbDebugPath; // NOLINTNEXTLINE(misc-use-internal-linkage) cl::opt SourceInDebugModule( "dx-source-in-debug-module", @@ -148,63 +150,61 @@ static void removeLifetimeIntrinsics(Module &M) { } class EmbedDXILPass : public llvm::ModulePass { - std::string writeModule(Module &M, bool HasDebugInfo, bool IsDebug) { + std::string writeModule(Module &M, bool WriteDebug) { std::string Data; llvm::raw_string_ostream OS(Data); - if (HasDebugInfo) { - if (IsDebug) { - if (!SourceInDebugModule) { - LLVMContext &Ctx = M.getContext(); - MDString *EmptyString = MDString::get(Ctx, ""); - if (NamedMDNode *Contents = - M.getNamedMetadata("dx.source.contents")) { - Contents->eraseFromParent(); - Metadata *Ops[2] = {EmptyString, EmptyString}; - M.getOrInsertNamedMetadata("dx.source.contents") - ->addOperand(MDTuple::get(Ctx, Ops)); - } - if (NamedMDNode *Defines = M.getNamedMetadata("dx.source.defines")) { - Defines->eraseFromParent(); - M.getOrInsertNamedMetadata("dx.source.defines") - ->addOperand(MDTuple::get(Ctx, {})); - } - if (NamedMDNode *MainFileName = - M.getNamedMetadata("dx.source.mainFileName")) { - MainFileName->eraseFromParent(); - Metadata *Ops[1] = {EmptyString}; - M.getOrInsertNamedMetadata("dx.source.mainFileName") - ->addOperand(MDTuple::get(Ctx, {Ops})); - } - if (NamedMDNode *Args = M.getNamedMetadata("dx.source.args")) { - Args->eraseFromParent(); - M.getOrInsertNamedMetadata("dx.source.args") - ->addOperand(MDTuple::get(Ctx, {})); - } + if (WriteDebug) { + if (!SourceInDebugModule) { + LLVMContext &Ctx = M.getContext(); + MDString *EmptyString = MDString::get(Ctx, ""); + if (NamedMDNode *Contents = + M.getNamedMetadata("dx.source.contents")) { + Contents->eraseFromParent(); + Metadata *Ops[2] = {EmptyString, EmptyString}; + M.getOrInsertNamedMetadata("dx.source.contents") + ->addOperand(MDTuple::get(Ctx, Ops)); + } + if (NamedMDNode *Defines = M.getNamedMetadata("dx.source.defines")) { + Defines->eraseFromParent(); + M.getOrInsertNamedMetadata("dx.source.defines") + ->addOperand(MDTuple::get(Ctx, {})); } - } else { - // If we have an ILDB part, strip DXIL from all debug info. - StripDebugInfo(M); - - // Also, manually remove debug version flags and dx.source nodes. - if (NamedMDNode *Flags = M.getModuleFlagsMetadata()) { - SmallVector FlagEntries; - M.getModuleFlagsMetadata(FlagEntries); - Flags->eraseFromParent(); - for (unsigned I : seq(FlagEntries.size())) { - llvm::Module::ModuleFlagEntry &Entry = FlagEntries[I]; - if (Entry.Key->getString() == "Dwarf Version" || - Entry.Key->getString() == "Debug Info Version") { - continue; - } - M.addModuleFlag(Entry.Behavior, Entry.Key->getString(), - cast(Entry.Val)->getValue()); + if (NamedMDNode *MainFileName = + M.getNamedMetadata("dx.source.mainFileName")) { + MainFileName->eraseFromParent(); + Metadata *Ops[1] = {EmptyString}; + M.getOrInsertNamedMetadata("dx.source.mainFileName") + ->addOperand(MDTuple::get(Ctx, {Ops})); + } + if (NamedMDNode *Args = M.getNamedMetadata("dx.source.args")) { + Args->eraseFromParent(); + M.getOrInsertNamedMetadata("dx.source.args") + ->addOperand(MDTuple::get(Ctx, {})); + } + } + } else { + // If we don't want debug info, strip it from DXIL. + StripDebugInfo(M); + + // Also, manually remove debug version flags and dx.source nodes. + if (NamedMDNode *Flags = M.getModuleFlagsMetadata()) { + SmallVector FlagEntries; + M.getModuleFlagsMetadata(FlagEntries); + Flags->eraseFromParent(); + for (unsigned I : seq(FlagEntries.size())) { + llvm::Module::ModuleFlagEntry &Entry = FlagEntries[I]; + if (Entry.Key->getString() == "Dwarf Version" || + Entry.Key->getString() == "Debug Info Version") { + continue; } + M.addModuleFlag(Entry.Behavior, Entry.Key->getString(), + cast(Entry.Val)->getValue()); } - for (NamedMDNode &NMD : llvm::make_early_inc_range(M.named_metadata())) - if (NMD.getName().starts_with("dx.source")) - NMD.eraseFromParent(); } + for (NamedMDNode &NMD : llvm::make_early_inc_range(M.named_metadata())) + if (NMD.getName().starts_with("dx.source")) + NMD.eraseFromParent(); } const auto DIMap = DebugInfoPass::run(M); @@ -239,19 +239,30 @@ 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) { + if (HasDebugInfo && (EmbedDebug || !PdbDebugPath.empty())) { // Write DXIL with debug info to ILDB part. // Clone the module to avoid alternating it with DebugInfoPass // before stripping the debug info later. - ILDBData = - writeModule(*llvm::CloneModule(M), HasDebugInfo, /*IsDebug=*/true); + ILDBData = writeModule(*llvm::CloneModule(M), /*WriteDebug=*/true); } // Clone the module to save dx.source metadata nodes from stripping, as they // are needed for DXILMetadataAnalysisWrapperPass. std::string DXILData = - writeModule(*llvm::CloneModule(M), HasDebugInfo, /*IsDebug=*/false); + writeModule(*llvm::CloneModule(M), /*WriteDebug=*/false); // TODO Do we need to run this pass on module itself? const auto DIMap = DebugInfoPass::run(M); @@ -262,7 +273,7 @@ class EmbedDXILPass : public llvm::ModulePass { removeLifetimeIntrinsics(M); SmallVector Globals; - if (HasDebugInfo) { + if (HasDebugInfo && (EmbedDebug || !PdbDebugPath.empty())) { // Create a GV after both parts are written, otherwise it gets // added to DXIL when `writeModule` is called the second time. Globals.emplace_back(createSectionGlobal(M, ILDBData, "dx.ildb", "ILDB")); diff --git a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp index c09fa0f8c2bd..2c45cbcc05df 100644 --- a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp +++ b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp @@ -54,6 +54,9 @@ using namespace llvm; +extern cl::opt EmbedDebug; +extern cl::opt PdbDebugPath; + extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() { RegisterTargetMachine X(getTheDirectXTarget()); diff --git a/llvm/test/CodeGen/DirectX/ContainerData/ContainerFlags.ll b/llvm/test/CodeGen/DirectX/ContainerData/ContainerFlags.ll new file mode 100644 index 000000000000..4a9410b4dc3b --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ContainerData/ContainerFlags.ll @@ -0,0 +1,34 @@ +;; 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 + +;; 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 + +;; 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 +; RUN: llvm-pdbutil dump --dxcontainer %t.pdb | FileCheck %s --check-prefix=PDB +; Check that PDB file contains only debug-info relevant parts. +; PDB: Parts: +; PDB: ILDB + +;; 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 deleted file mode 100644 index c1f84158cd22..000000000000 --- a/llvm/test/CodeGen/DirectX/ContainerData/DebugName-default-output.test +++ /dev/null @@ -1,17 +0,0 @@ -RUN: llc %S/Inputs/SourceInfo.ll -dx-Zss --filetype=obj -o %t.dxbc -RUN: llvm-objcopy --dump-section=ILDB=%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 -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/DebugName-user-directory.test b/llvm/test/CodeGen/DirectX/ContainerData/DebugName-user-directory.test index 1b94fce1bcd4..11c4ffee22f3 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/DebugName-user-directory.test +++ b/llvm/test/CodeGen/DirectX/ContainerData/DebugName-user-directory.test @@ -1,11 +1,13 @@ RUN: rm -rf %t && mkdir %t -RUN: llc %S/Inputs/SourceInfo.ll -dx-Zss --filetype=obj -o %t.dxbc --dx-pdb-dir=%t +RUN: llc %S/Inputs/SourceInfo.ll -dx-Zss -dx-embed-debug --filetype=obj -o %t.dxbc --dx-Fd=%t/ RUN: llvm-objcopy --dump-section=ILDB=%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 RUN: %python %S/Inputs/check_pdb_exists.py "%t" "%t0.bc.md5" +CHECK-NOT: - Name: PDBN +CHECK-NOT: - Name: PDBH CHECK: - Name: ILDN CHECK-NEXT: Size: {{.*}} CHECK-NEXT: DebugName: diff --git a/llvm/test/CodeGen/DirectX/ContainerData/DebugName-user-specified.test b/llvm/test/CodeGen/DirectX/ContainerData/DebugName-user-specified.test index 9cacf78904ec..a2a8a3d1d79e 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/DebugName-user-specified.test +++ b/llvm/test/CodeGen/DirectX/ContainerData/DebugName-user-specified.test @@ -1,5 +1,5 @@ RUN: rm -rf %t && mkdir %t -RUN: llc %S/Inputs/SourceInfo.ll --filetype=obj -o - --dx-pdb-file=%t/ofile.pdb | obj2yaml | FileCheck %s +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 diff --git a/llvm/test/CodeGen/DirectX/ContainerData/DebugName.test b/llvm/test/CodeGen/DirectX/ContainerData/DebugName.test index cdbba8bddacf..3d42707d25d6 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/DebugName.test +++ b/llvm/test/CodeGen/DirectX/ContainerData/DebugName.test @@ -1,6 +1,7 @@ # 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 -S -o - | FileCheck %s --check-prefix=BC +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 diff --git a/llvm/test/CodeGen/DirectX/ContainerData/PDBParts.test b/llvm/test/CodeGen/DirectX/ContainerData/PDBParts.test index c4128a8b20ba..9adca7eb2281 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 dump --streams --dxcontainer %t/parts.pdb | FileCheck %s --check-prefix=PDB # Check that debug-related container parts are emitted into companion PDB file. diff --git a/llvm/test/CodeGen/DirectX/embed-ildb.ll b/llvm/test/CodeGen/DirectX/embed-ildb.ll index 9511e0e6a4ba..6f5b648b4d18 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