https://github.com/kuilpd updated https://github.com/llvm/llvm-project/pull/204415
>From d405259c9cb7270a4725208679cebb64268bc38e Mon Sep 17 00:00:00 2001 From: Ilia Kuklin <[email protected]> Date: Wed, 17 Jun 2026 19:40:08 +0500 Subject: [PATCH 1/2] Add /Qsource_in_debug_module flag --- clang/include/clang/Options/Options.td | 3 + clang/lib/Driver/ToolChains/Clang.cpp | 4 + clang/test/Driver/dxc_debug.hlsl | 2 + .../lib/Target/DirectX/DXContainerGlobals.cpp | 3 +- .../Target/DirectX/DXILTranslateMetadata.cpp | 11 +- .../DirectX/DXILWriter/DXILWriterPass.cpp | 24 ++-- .../DirectX/ContainerData/SourceInfo-Strip.ll | 110 ++++++++++++++++++ llvm/test/CodeGen/DirectX/embed-ildb.ll | 4 + 8 files changed, 147 insertions(+), 14 deletions(-) create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Strip.ll diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 59bfd621a5994..da85cb989c37a 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -9737,6 +9737,9 @@ 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_source_in_debug_module + : DXCFlag<"Qsource_in_debug_module">, + HelpText<"Embed source code into PDB debug module">; 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 a30b01a675b99..ace12bb8ec19f 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3978,6 +3978,10 @@ 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. + if (Args.hasArg(options::OPT_dxc_source_in_debug_module)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("--dx-source-in-debug-module"); + } } 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..6f37e59d4cf32 100644 --- a/clang/test/Driver/dxc_debug.hlsl +++ b/clang/test/Driver/dxc_debug.hlsl @@ -4,6 +4,7 @@ // 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 -Qsource_in_debug_module %s 2>&1 | FileCheck %s --check-prefix=CHECK,CHECK-SIDM // 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 @@ -16,6 +17,7 @@ // CHECK-DWARF-SAME: -dwarf-version=4 // Check that the flags are converted to their llc equivalents. // CHECK-ZSS-SAME: -dx-Zss +// CHECK-SIDM-SAME: --dx-source-in-debug-module // 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 diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp index 47396b8c33580..7b033c3249008 100644 --- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp +++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp @@ -46,6 +46,7 @@ cl::opt<std::string> PdbDebugPath( cl::desc("Write debug information to the given file, or automatically " "named file in directory when ending in '/'"), cl::value_desc("filename")); +extern cl::opt<bool> SourceInDebugModule; namespace { class DXContainerGlobals : public llvm::ModulePass { @@ -397,7 +398,7 @@ void DXContainerGlobals::addSourceInfo(Module &M, dxil::ModuleMetadataInfo &MMI = getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata(); - if (!MMI.SourceInfo) + if (!MMI.SourceInfo || SourceInDebugModule) return; MMI.SourceInfo->computeEntries(); diff --git a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp index 49a20e2f7517a..240d5814d33d4 100644 --- a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp +++ b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp @@ -514,15 +514,18 @@ static void cleanModuleFlags(Module &M) { M.addModuleFlag(Flag.Behavior, Flag.Key->getString(), Flag.Val); } -using GlobalMDList = std::array<StringLiteral, 7>; +using GlobalMDList = std::array<StringLiteral, 11>; // The following are compatible with DXIL but not emit with clang, they can // be added when applicable: // dx.typeAnnotations, dx.viewIDState, dx.dxrPayloadAnnotations static GlobalMDList CompatibleNamedModuleMDs = { - "llvm.ident", "llvm.module.flags", "dx.resources", "dx.valver", - "dx.shaderModel", "dx.version", "dx.entryPoints", -}; + "llvm.ident", "llvm.module.flags", + "dx.resources", "dx.valver", + "dx.shaderModel", "dx.version", + "dx.entryPoints", "dx.source.contents", + "dx.source.defines", "dx.source.mainFileName", + "dx.source.args"}; static void translateGlobalMetadata(Module &M, DXILResourceMap &DRM, DXILResourceTypeMap &DRTM, diff --git a/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp index 9bbb87327d749..c17b571d41ce3 100644 --- a/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp +++ b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp @@ -29,6 +29,7 @@ #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/Alignment.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/ModuleUtils.h" @@ -37,6 +38,10 @@ using namespace llvm::dxil; extern cl::opt<bool> EmbedDebug; extern cl::opt<std::string> PdbDebugPath; +cl::opt<bool> SourceInDebugModule( + "dx-source-in-debug-module", + cl::desc("Embed source code into debug module on DirectX target"), + cl::init(false)); namespace { class WriteDXILPass : public llvm::ModulePass { @@ -160,15 +165,16 @@ class EmbedDXILPass : public llvm::ModulePass { if (HasDebugInfo) { if (WriteDebug) { - // Replace dx.source metadata nodes with stubs. - // TODO: Add /Qsource_in_debug_module flag to enable/disable this. - LLVMContext &Ctx = M.getContext(); - MDString *EmptyString = MDString::get(Ctx, ""); - replaceNamedMetadataArray(M, "dx.source.contents", - {EmptyString, EmptyString}); - replaceNamedMetadataArray(M, "dx.source.defines", {}); - replaceNamedMetadataArray(M, "dx.source.mainFileName", {EmptyString}); - replaceNamedMetadataArray(M, "dx.source.args", {}); + if (!SourceInDebugModule) { + // Replace dx.source metadata nodes with stubs. + LLVMContext &Ctx = M.getContext(); + MDString *EmptyString = MDString::get(Ctx, ""); + replaceNamedMetadataArray(M, "dx.source.contents", + {EmptyString, EmptyString}); + replaceNamedMetadataArray(M, "dx.source.defines", {}); + replaceNamedMetadataArray(M, "dx.source.mainFileName", {EmptyString}); + replaceNamedMetadataArray(M, "dx.source.args", {}); + } } else { // If we have an ILDB part, strip DXIL from all debug info. StripDebugInfo(M); diff --git a/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Strip.ll b/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Strip.ll new file mode 100644 index 0000000000000..27590cf9bb5c3 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Strip.ll @@ -0,0 +1,110 @@ +; Compare source info emission with and without --dx-source-in-debug-module flag. + +; RUN: llc %s --filetype=obj -o %t.dxbc --dx-pdb-path=%t.pdb +; RUN: llvm-pdbutil export --stream=5 --out=%t.pdb.dxbc %t.pdb +; RUN: obj2yaml %t.pdb.dxbc | FileCheck %s --check-prefix=DXC +; RUN: llvm-objcopy --dump-section=DXIL=%t.dxil.bc %t.dxbc +; RUN: llvm-dis %t.dxil.bc -o - | FileCheck %s --check-prefix=DXIL-DIS +; RUN: llvm-objcopy --dump-section=ILDB=%t.ildb.bc %t.pdb.dxbc +; RUN: llvm-dis %t.ildb.bc -o - | FileCheck %s --check-prefix=ILDB-DIS + +; RUN: llc %s --filetype=obj -o %t.dxbc --dx-source-in-debug-module --dx-pdb-path=%t.pdb +; RUN: llvm-pdbutil export --stream=5 --out=%t.pdb.dxbc %t.pdb +; RUN: obj2yaml %t.pdb.dxbc | FileCheck %s --check-prefix=DXC-SOURCE +; RUN: llvm-objcopy --dump-section=DXIL=%t.dxil.bc %t.dxbc +; RUN: llvm-dis %t.dxil.bc -o - | FileCheck %s --check-prefix=DXIL-SOURCE-DIS +; RUN: llvm-objcopy --dump-section=ILDB=%t.ildb.bc %t.pdb.dxbc +; RUN: llvm-dis %t.ildb.bc -o - | FileCheck %s --check-prefix=ILDB-SOURCE-DIS + +; Without the flag, dx.source should be stripped away from DXIL, and replaced +; with dummy metadata in ILDB. +; DXIL-DIS-NOT: dx.source +; ILDB-DIS: !dx.source.contents = !{![[CONTENTS:[0-9]+]]} +; ILDB-DIS: !dx.source.defines = !{![[EMPTY_ARR:[0-9]+]]} +; ILDB-DIS: !dx.source.mainFileName = !{![[MAIN:[0-9]+]]} +; ILDB-DIS: !dx.source.args = !{![[EMPTY_ARR]]} +; ILDB-DIS: ![[CONTENTS]] = !{!"", !""} +; ILDB-DIS: ![[EMPTY_ARR]] = !{} +; ILDB-DIS: ![[MAIN]] = !{!""} + +; Without the flag, SRCI should be emitted. +; DXC: - Name: SRCI +; DXC-NEXT: Size: 348 +; DXC-NEXT: SourceInfo: +; DXC-NEXT: Header: +; DXC: SectionCount: 3 +; DXC-NEXT: Names: +; DXC-NEXT: SectionHeader: +; DXC: Type: SourceNames +; DXC-NEXT: Header: +; DXC: Count: 3 +; DXC: Entries: +; DXC: FileName: 'C:\dx-source-metadata.hlsl' +; DXC: FileName: 'C:\a.hlsl' +; DXC: FileName: 'C:\b.hlsl' +; DXC-NEXT: Contents: +; DXC-NEXT: SectionHeader: +; DXC: Type: SourceContents +; DXC-NEXT: Header: +; DXC: Count: 3 +; DXC: Entries: +; DXC: FileContent: "#include \"a.hlsl\"\n#include \"b.hlsl\"\n\nfloat foo(float a, float b) {\n return a + b;\n}\n" +; DXC: FileContent: "#include \"b.hlsl\"\n" +; DXC: FileContent: "#include <c.hlsl>\n" +; DXC: Args: +; DXC: SectionHeader: +; DXC: Header: +; DXC: Count: 5 +; DXC: Args: +; DXC-NEXT: - Arg: '-g' +; DXC-NEXT: Value: '' +; DXC-NEXT: - Arg: '-Tlib_6_3' +; DXC-NEXT: Value: '' +; DXC-NEXT: - Arg: '-DUSER_DEF0=42' +; DXC-NEXT: Value: '' +; DXC-NEXT: - Arg: '-DUSER_DEF1=43' +; DXC-NEXT: Value: '' +; DXC-NEXT: - Arg: 'C:\\dx-source-metadata.hlsl' +; DXC-NEXT: Value: '' + +; With the flag, dx.source should be stripped away from DXIL, and kept untouched in ILDB. +; DXIL-SOURCE-DIS-NOT: dx.source +; ILDB-SOURCE-DIS: !dx.source.args = !{![[ARGS:[0-9]+]]} +; ILDB-SOURCE-DIS: !dx.source.contents = !{![[FILE1:[0-9]+]], ![[FILE2:[0-9]+]], ![[FILE3:[0-9]+]]} +; ILDB-SOURCE-DIS: !dx.source.mainFileName = !{![[MAIN:[0-9]+]]} +; ILDB-SOURCE-DIS: !dx.source.defines = !{![[DEFINES:[0-9]+]]} +; ILDB-SOURCE-DIS: ![[FILE1]] = !{!"C:\\dx-source-metadata.hlsl", +; ILDB-SOURCE-DIS: ![[FILE2]] = !{!"C:\\a.hlsl" +; ILDB-SOURCE-DIS: ![[FILE3]] = !{!"C:\\b.hlsl" +; ILDB-SOURCE-DIS: ![[MAIN]] = !{!"C:\\dx-source-metadata.hlsl"} +; ILDB-SOURCE-DIS: ![[DEFINES]] = !{!"USER_DEF0=42", !"USER_DEF1=43"} + +; With the flag, SRCI should not be emitted. +; DXC-SOURCE-NOT: - Name: SRCI + +target triple = "dxilv1.3-pc-shadermodel6.3-library" + +define float @_Z3fooff(float %a, float %b) { +entry: + %add = fadd float %a, %b + ret float %add +} + +!llvm.dbg.cu = !{!4} +!llvm.module.flags = !{!6, !7} + +!dx.source.args = !{!0} +!dx.source.contents = !{!1, !2, !3} +!dx.source.mainFileName = !{!8} +!dx.source.defines = !{!9} + +!0 = !{!"-g", !"-Tlib_6_3", !"-DUSER_DEF0=42", !"-DUSER_DEF1=43", !"C:\\\\dx-source-metadata.hlsl"} +!1 = !{!"C:\\dx-source-metadata.hlsl", !"#include \22a.hlsl\22\0A#include \22b.hlsl\22\0A\0Afloat foo(float a, float b) {\0A return a + b;\0A}\0A"} +!2 = !{!"C:\\a.hlsl", !"#include \22b.hlsl\22\0A"} +!3 = !{!"C:\\b.hlsl", !"#include <c.hlsl>\0A"} +!4 = distinct !DICompileUnit(language: DW_LANG_C99, file: !5, emissionKind: FullDebug) +!5 = !DIFile(filename: "dx-source-metadata.hlsl", directory: "C:\\") +!6 = !{i32 2, !"Dwarf Version", i32 4} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{!"C:\\dx-source-metadata.hlsl"} +!9 = !{!"USER_DEF0=42", !"USER_DEF1=43"} diff --git a/llvm/test/CodeGen/DirectX/embed-ildb.ll b/llvm/test/CodeGen/DirectX/embed-ildb.ll index b1203bb1b3fcf..c0c9545017944 100644 --- a/llvm/test/CodeGen/DirectX/embed-ildb.ll +++ b/llvm/test/CodeGen/DirectX/embed-ildb.ll @@ -93,6 +93,10 @@ define i32 @add(i32 %a, i32 %b) { ; ILDB-DIS: define i32 @add(i32 %a, i32 %b) ; ILDB-DIS: !llvm.dbg.cu +; ILDB-DIS: !dx.source.contents +; ILDB-DIS: !dx.source.defines +; ILDB-DIS: !dx.source.mainFileName +; ILDB-DIS: !dx.source.args ; ILDB-DIS: !DICompileUnit ; ILDB-DIS: !DIFile ; ILDB-DIS: !"Dwarf Version" >From 6da162e0523272e8d0e402cca7a0dccb3fc02cab Mon Sep 17 00:00:00 2001 From: Ilia Kuklin <[email protected]> Date: Thu, 9 Jul 2026 17:14:58 +0500 Subject: [PATCH 2/2] Skip checking the size --- llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Strip.ll | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Strip.ll b/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Strip.ll index 27590cf9bb5c3..f7792b38e04c5 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Strip.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Strip.ll @@ -29,8 +29,7 @@ ; Without the flag, SRCI should be emitted. ; DXC: - Name: SRCI -; DXC-NEXT: Size: 348 -; DXC-NEXT: SourceInfo: +; DXC: SourceInfo: ; DXC-NEXT: Header: ; DXC: SectionCount: 3 ; DXC-NEXT: Names: _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
