https://github.com/kuilpd updated https://github.com/llvm/llvm-project/pull/204415
>From 3cc2c77695a36deba1e9761efa34894a14e91836 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 e2a14d364f457..4eba48a18a002 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -9677,6 +9677,9 @@ def dxc_Zi : Option<["/", "-"], "Zi", KIND_FLAG>, Alias<g_Flag>, Visibility<[CLOption, DXCOption]>, HelpText<"Enable debug information">; +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 b3b8280de3006..94b309e019568 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3873,6 +3873,10 @@ static void RenderHLSLOptions(const Driver &D, const ArgList &Args, CmdArgs.push_back("-mllvm"); CmdArgs.push_back(Args.MakeArgString("--dx-Fd=" + Twine(Fd->getValue()))); } + 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 d90be0bb5bad2..794709141ff09 100644 --- a/clang/test/Driver/dxc_debug.hlsl +++ b/clang/test/Driver/dxc_debug.hlsl @@ -6,6 +6,7 @@ // 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 -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 @@ -20,6 +21,7 @@ // CHECK-EMBED-SAME: --dx-embed-debug // CHECK-FD-SAME: --dx-Fd= // 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 16facaf13b96b..9b2bd83ba595f 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..4eab09b793e12 --- /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-Fd=%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-Fd=%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 84bdad2b39e08..793717cec2963 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 7f6b287b50a78d7666994ab1d76bafd058584eab Mon Sep 17 00:00:00 2001 From: Ilia Kuklin <[email protected]> Date: Fri, 26 Jun 2026 20:55:05 +0500 Subject: [PATCH 2/2] [DirectX] Test stripping debug info for DirectX (#204874) Test that all debug info is stripped after changes in #201336. --- llvm/test/CodeGen/DirectX/strip-debug-info.ll | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 llvm/test/CodeGen/DirectX/strip-debug-info.ll diff --git a/llvm/test/CodeGen/DirectX/strip-debug-info.ll b/llvm/test/CodeGen/DirectX/strip-debug-info.ll new file mode 100644 index 0000000000000..446e9ce5e4f06 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/strip-debug-info.ll @@ -0,0 +1,92 @@ +; RUN: llc %s --filetype=obj -o %t.bc +; RUN: llvm-objcopy --dump-section=ILDB=%t.ildb %t.bc +; RUN: llvm-objcopy --dump-section=DXIL=%t.dxil %t.bc +; RUN: dxil-dis %t.ildb -o - | FileCheck %s --check-prefix=ILDB-DIS +; RUN: dxil-dis %t.dxil -o - | FileCheck %s --check-prefix=DXIL-DIS + +;; Check that the debug info is emitted into ILDB part +; ILDB-DIS: define void @foo +; ILDB-DIS-DAG: @llvm.dbg.declare +; ILDB-DIS-DAG: @llvm.dbg.assign +; ILDB-DIS-DAG: @llvm.dbg.value +; ILDB-DIS-DAG: @llvm.dbg.label +; ILDB-DIS-DAG: !llvm.dbg.cu +; ILDB-DIS-DAG: !dx.source +; ILDB-DIS-DAG: !DICompileUnit +; ILDB-DIS-DAG: !DIFile +; ILDB-DIS-DAG: !"Dwarf Version" +; ILDB-DIS-DAG: !"Debug Info Version" +; ILDB-DIS-DAG: "foo.hlsl" +; ILDB-DIS-DAG: !DISubprogram +; ILDB-DIS-DAG: !DISubroutineType +; ILDB-DIS-DAG: !DIBasicType +; ILDB-DIS-DAG: !DILocation +; ILDB-DIS-DAG: !DILocalVariable +; ILDB-DIS-DAG: !DIGlobalVariable + +;; Check that all the debug info is properly stripped from DXIL part +; DXIL-DIS: define void @foo +; DXIL-DIS-NOT: @llvm.dbg +; DXIL-DIS-NOT: !llvm.dbg.cu +; DXIL-DIS-NOT: !dx.source +; DXIL-DIS-NOT: !DICompileUnit +; DXIL-DIS-NOT: !DIFile +; DXIL-DIS-NOT: !"Dwarf Version" +; DXIL-DIS-NOT: !"Debug Info Version" +; DXIL-DIS-NOT: "foo.hlsl" +; DXIL-DIS-NOT: !DISubprogram +; DXIL-DIS-NOT: !DISubroutineType +; DXIL-DIS-NOT: !DILabel +; DXIL-DIS-NOT: !DIBasicType +; DXIL-DIS-NOT: !DILocation +; DXIL-DIS-NOT: !DILocalVariable +; DXIL-DIS-NOT: !DIGlobalVariable + +target triple = "dxil-pc-shadermodel6.3-library" + +@g = global i32 0, align 4, !dbg !21 + +define void @foo(i32 %i) !dbg !4 { +entry: + %a = alloca i32, align 4 + #dbg_declare(ptr %a, !17, !DIExpression(), !18) + #dbg_assign(ptr %a, !17, !DIExpression(), !19, ptr poison, !DIExpression(), !18) + + #dbg_value(i32 %i, !9, !DIExpression(), !11) + br label %label + +label: + #dbg_label(!8, !12) + ret void +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3} +!dx.source.contents = !{!13} +!dx.source.defines = !{!14} +!dx.source.mainFileName = !{!15} +!dx.source.args = !{!16} + +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !20) +!1 = !DIFile(filename: "foo.hlsl", directory: "") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !7) +!5 = !DISubroutineType(types: !6) +!6 = !{null} +!7 = !{!8} +!8 = !DILabel(scope: !4, name: "label", file: !1, line: 2, column: 1) +!9 = !DILocalVariable(name: "i", arg: 1, scope: !4, file: !1, line: 4, type: !10) +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DILocation(line: 1, column: 1, scope: !4) +!12 = !DILocation(line: 33, column: 1, scope: !4) +!13 = !{!"foo.hlsl", !"static int g; export void foo(int i) { int a; return; }"} +!14 = !{} +!15 = !{!"foo.hlsl"} +!16 = !{!"--driver-mode=dxc", !"-g", !"-T", !"lib_6_3", !"foo.hlsl"} +!17 = !DILocalVariable(name: "a", arg: 2, scope: !4, file: !1, line: 1, type: !10) +!18 = !DILocation(line: 1, column: 30, scope: !4) +!19 = distinct !DIAssignID() +!20 = !{!21} +!21 = !DIGlobalVariableExpression(var: !22, expr: !DIExpression()) +!22 = distinct !DIGlobalVariable(name: "g", scope: !0, file: !1, line: 1, type: !10, isLocal: false, isDefinition: true) _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
