[llvm] [DirectX] Write DXIL with debug info to ILDB part (PR #201423)
Ilia Kuklin via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 8 03:43:31 PDT 2026
https://github.com/kuilpd updated https://github.com/llvm/llvm-project/pull/201423
>From 7e1d20d0fc04a3799b768be838eb741cd90b4284 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Wed, 3 Jun 2026 01:43:03 +0500
Subject: [PATCH 1/3] [DirectX] Write DXIL with debug info to ILDB part
---
llvm/include/llvm/BinaryFormat/DXContainer.h | 1 +
llvm/lib/BinaryFormat/DXContainer.cpp | 4 +
llvm/lib/MC/MCDXContainerWriter.cpp | 6 +-
.../lib/Target/DirectX/DXContainerGlobals.cpp | 6 +-
.../DirectX/DXILWriter/DXILWriterPass.cpp | 102 +++++++++++++++---
.../DirectX/ContainerData/DebugShaderHash.ll | 4 +-
llvm/test/CodeGen/DirectX/embed-ildb.ll | 98 +++++++++++++++++
llvm/test/tools/dxil-dis/dbg-declare-undef.ll | 4 +-
llvm/test/tools/dxil-dis/dbg-value.ll | 4 +-
llvm/test/tools/dxil-dis/debug-info.ll | 4 +-
.../di-compile-unit-versioned-language.ll | 4 +-
llvm/test/tools/dxil-dis/di-compile-unit.ll | 4 +-
llvm/test/tools/dxil-dis/di-label.ll | 4 +-
llvm/test/tools/dxil-dis/di-subprogram.ll | 4 +-
llvm/test/tools/dxil-dis/di-subrange.ll | 4 +-
llvm/test/tools/dxil-dis/di-subrangetype.ll | 4 +-
llvm/test/tools/dxil-dis/vla.ll | 4 +-
17 files changed, 228 insertions(+), 33 deletions(-)
create mode 100644 llvm/test/CodeGen/DirectX/embed-ildb.ll
diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h
index a93d99693eb87..84c822ddbd2cb 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainer.h
+++ b/llvm/include/llvm/BinaryFormat/DXContainer.h
@@ -263,6 +263,7 @@ LLVM_ABI PartType parsePartType(StringRef S);
bool isDebugProgramPart(PartType PT);
const char *getProgramPartName(bool IsDebug);
+bool isProgramPart(StringRef PartName);
struct VertexPSVInfo {
uint8_t OutputPositionPresent;
diff --git a/llvm/lib/BinaryFormat/DXContainer.cpp b/llvm/lib/BinaryFormat/DXContainer.cpp
index b980f2cf1865c..46d91347742b2 100644
--- a/llvm/lib/BinaryFormat/DXContainer.cpp
+++ b/llvm/lib/BinaryFormat/DXContainer.cpp
@@ -133,6 +133,10 @@ const char *dxbc::getProgramPartName(bool IsDebug) {
return IsDebug ? "ILDB" : "DXIL";
}
+bool dxbc::isProgramPart(StringRef PartName) {
+ return PartName == "DXIL" || PartName == "ILDB";
+}
+
bool ShaderHash::isPopulated() {
static uint8_t Zeros[16] = {0};
return Flags > 0 || 0 != memcmp(&Digest, &Zeros, 16);
diff --git a/llvm/lib/MC/MCDXContainerWriter.cpp b/llvm/lib/MC/MCDXContainerWriter.cpp
index ebed411454087..e027d543ce5d8 100644
--- a/llvm/lib/MC/MCDXContainerWriter.cpp
+++ b/llvm/lib/MC/MCDXContainerWriter.cpp
@@ -39,7 +39,7 @@ uint64_t DXContainerObjectWriter::writeObject() {
PartOffset = alignTo(PartOffset, Align(4ul));
// The DXIL part also writes a program header, so we need to include its
// size when computing the offset for a part after the DXIL part.
- if (Sec.getName() == "DXIL")
+ if (dxbc::isProgramPart(Sec.getName()))
PartOffset += sizeof(dxbc::ProgramHeader);
}
assert(PartOffset < std::numeric_limits<uint32_t>::max() &&
@@ -78,12 +78,12 @@ uint64_t DXContainerObjectWriter::writeObject() {
uint64_t PartSize = SectionSize;
- if (Sec.getName() == "DXIL")
+ if (dxbc::isProgramPart(Sec.getName()))
PartSize += sizeof(dxbc::ProgramHeader);
// DXContainer parts should be 4-byte aligned.
PartSize = alignTo(PartSize, Align(4));
W.write<uint32_t>(static_cast<uint32_t>(PartSize));
- if (Sec.getName() == "DXIL") {
+ if (dxbc::isProgramPart(Sec.getName())) {
dxbc::ProgramHeader Header;
memset(reinterpret_cast<void *>(&Header), 0, sizeof(dxbc::ProgramHeader));
diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index 7fef7436f3874..9a68961473dbd 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -113,17 +113,13 @@ 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());
MD5 Digest;
Digest.update(DXILConstant->getRawDataValues());
MD5::MD5Result Result = Digest.final();
-
dxbc::ShaderHash HashData = {0, {0}};
- // The Hash's IncludesSource flag gets set whenever the hashed shader includes
- // debug information.
- if (!M.debug_compile_units().empty())
- HashData.Flags = static_cast<uint32_t>(dxbc::HashFlags::IncludesSource);
memcpy(reinterpret_cast<void *>(&HashData.Digest), Result.data(), 16);
if (sys::IsBigEndianHost)
diff --git a/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp
index f74accc3b8619..6b249a5b309e5 100644
--- a/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp
+++ b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp
@@ -18,6 +18,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/ModuleSummaryAnalysis.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IntrinsicInst.h"
@@ -28,6 +29,7 @@
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Alignment.h"
+#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
using namespace llvm;
@@ -138,7 +140,72 @@ static void removeLifetimeIntrinsics(Module &M) {
}
}
+static void replaceNamedMetadataArray(Module &M, StringRef Name,
+ ArrayRef<Metadata *> NewOps) {
+ NamedMDNode *NMD = M.getNamedMetadata(Name);
+ if (!NMD)
+ return;
+ NMD->eraseFromParent();
+ M.getOrInsertNamedMetadata(Name)->addOperand(
+ MDTuple::get(M.getContext(), NewOps));
+}
+
class EmbedDXILPass : public llvm::ModulePass {
+ std::string writeModule(Module &M, bool HasDebugInfo, bool WriteDebug) {
+ std::string Data;
+ llvm::raw_string_ostream OS(Data);
+
+ 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", {});
+ } 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<llvm::Module::ModuleFlagEntry, 4> FlagEntries;
+ M.getModuleFlagsMetadata(FlagEntries);
+ Flags->eraseFromParent();
+ for (llvm::Module::ModuleFlagEntry &Entry : FlagEntries) {
+ if (Entry.Key->getString() == "Dwarf Version" ||
+ Entry.Key->getString() == "Debug Info Version") {
+ continue;
+ }
+ M.addModuleFlag(Entry.Behavior, Entry.Key->getString(), Entry.Val);
+ }
+ }
+ for (NamedMDNode &NMD : llvm::make_early_inc_range(M.named_metadata()))
+ if (NMD.getName().starts_with("dx.source"))
+ NMD.eraseFromParent();
+ }
+ }
+ const auto DIMap = DXILDebugInfoPass::run(M);
+ WriteDXILToFile(M, OS, DIMap);
+ return Data;
+ }
+
+ GlobalVariable *createSectionGlobal(Module &M, StringRef Data,
+ StringRef GlobalName,
+ StringRef SectionName) {
+ Constant *ModuleConstant =
+ ConstantDataArray::get(M.getContext(), arrayRefFromStringRef(Data));
+ auto *GV = new llvm::GlobalVariable(M, ModuleConstant->getType(), true,
+ GlobalValue::PrivateLinkage,
+ ModuleConstant, GlobalName);
+ GV->setSection(SectionName);
+ GV->setAlignment(Align(4));
+ return GV;
+ }
+
public:
static char ID; // Pass identification, replacement for typeid
EmbedDXILPass() : ModulePass(ID) {
@@ -148,29 +215,38 @@ class EmbedDXILPass : public llvm::ModulePass {
StringRef getPassName() const override { return "DXIL Embedder"; }
bool runOnModule(Module &M) override {
- std::string Data;
- llvm::raw_string_ostream OS(Data);
-
// Perform late legalization of lifetime intrinsics that would otherwise
// fail the Module Verifier if performed in an earlier pass
legalizeLifetimeIntrinsics(M);
- const auto DIMap = DXILDebugInfoPass::run(M);
- WriteDXILToFile(M, OS, DIMap);
+ bool HasDebugInfo = !M.debug_compile_units().empty();
+ std::string ILDBData;
+ if (HasDebugInfo) {
+ // 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, /*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, /*WriteDebug=*/false);
// We no longer need lifetime intrinsics after bitcode serialization, so we
// simply remove them to keep the Module Verifier happy after our
// not-so-legal legalizations
removeLifetimeIntrinsics(M);
- Constant *ModuleConstant =
- ConstantDataArray::get(M.getContext(), arrayRefFromStringRef(Data));
- auto *GV = new llvm::GlobalVariable(M, ModuleConstant->getType(), true,
- GlobalValue::PrivateLinkage,
- ModuleConstant, "dx.dxil");
- GV->setSection("DXIL");
- GV->setAlignment(Align(4));
- appendToCompilerUsed(M, {GV});
+ SmallVector<GlobalValue *, 2> Globals;
+ if (HasDebugInfo) {
+ // 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"));
+ }
+ Globals.emplace_back(createSectionGlobal(M, DXILData, "dx.dxil", "DXIL"));
+ appendToCompilerUsed(M, Globals);
return true;
}
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/DebugShaderHash.ll b/llvm/test/CodeGen/DirectX/ContainerData/DebugShaderHash.ll
index eda0d6850bde5..c0febd5bf758d 100644
--- a/llvm/test/CodeGen/DirectX/ContainerData/DebugShaderHash.ll
+++ b/llvm/test/CodeGen/DirectX/ContainerData/DebugShaderHash.ll
@@ -2,7 +2,7 @@
; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
target triple = "dxil-unknown-shadermodel6.5-library"
-; CHECK: @dx.hash = private constant [20 x i8] c"\01\00\00\00{{.*}}", section "HASH", align 4
+; CHECK: @dx.hash = private constant [20 x i8] c"\00\00\00\00{{.*}}", section "HASH", align 4
define i32 @add(i32 %a, i32 %b) {
%sum = add i32 %a, %b
@@ -21,5 +21,5 @@ define i32 @add(i32 %a, i32 %b) {
; DXC: - Name: HASH
; DXC: Size: 20
; DXC: Hash:
-; DXC: IncludesSource: true
+; DXC: IncludesSource: false
; DXC: Digest: [
diff --git a/llvm/test/CodeGen/DirectX/embed-ildb.ll b/llvm/test/CodeGen/DirectX/embed-ildb.ll
new file mode 100644
index 0000000000000..1f4289f3b725e
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/embed-ildb.ll
@@ -0,0 +1,98 @@
+; RUN: opt %s -dxil-embed -dxil-globals -S -o - | FileCheck %s
+; RUN: llc %s --filetype=obj -o %t.bc
+; 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
+; RUN: llvm-dis %t.ildb -o - | FileCheck %s --check-prefix=ILDB-DIS
+; RUN: llvm-dis %t.dxil -o - | FileCheck %s --check-prefix=DXIL-DIS
+
+target triple = "dxil-unknown-shadermodel6.5-library"
+; CHECK: target triple = "dxil-unknown-shadermodel6.5-library"
+
+define i32 @add(i32 %a, i32 %b) {
+ %sum = add i32 %a, %b
+ ret i32 %sum
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4}
+!dx.source.contents = !{!5}
+!dx.source.defines = !{!6}
+!dx.source.mainFileName = !{!7}
+!dx.source.args = !{!8}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Some Compiler", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "hlsl.hlsl", directory: "/some-path")
+!2 = !{}
+!3 = !{i32 7, !"Dwarf Version", i32 2}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{!"hlsl.hlsl", !"int add(int a, int b) { return a + b; }"}
+!6 = !{}
+!7 = !{!"hlsl.hlsl"}
+!8 = !{!"-T", !"lib_6_5", !"-g", !"hlsl.hlsl"}
+
+; Check that both 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: @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
+; going to change as the DirectX backend continues to evolve and implement more
+; features. Rather than extending this test to cover those future features, this
+; test's matches are extremely fuzzy so that it won't break.
+
+; YAML: --- !dxcontainer
+; YAML-NEXT: Header:
+; YAML-NEXT: Hash: [ 0x0, 0x0, 0x0,
+; YAML: Version:
+; YAML-NEXT: Major: 1
+; YAML-NEXT: Minor: 0
+; YAML-NEXT: FileSize: [[#]]
+; YAML-NEXT: PartCount: [[#]]
+; YAML-NEXT: PartOffsets: [ {{[0-9, ]+}}
+; YAML: Parts:
+
+; In verifying the DXIL and ILDB parts, this test captures the size of the part,
+; and derives the program header and dxil size fields from the part's size.
+
+; YAML: - Name: ILDB
+; YAML-NEXT: Size: [[#ILDBSIZE:]]
+; YAML-NEXT: Program:
+; YAML-NEXT: MajorVersion: 6
+; YAML-NEXT: MinorVersion: 5
+; YAML-NEXT: ShaderKind: 6
+; YAML-NEXT: Size: [[#div(ILDBSIZE,4)]]
+; YAML-NEXT: DXILMajorVersion: 1
+; YAML-NEXT: DXILMinorVersion: 5
+; YAML-NEXT: DXILSize: [[#ILDBSIZE - 24]]
+; YAML-NEXT: DXIL: [ 0x42, 0x43, 0xC0, 0xDE,
+; YAML: - Name: DXIL
+; YAML-NEXT: Size: [[#DXILSIZE:]]
+; YAML-NEXT: Program:
+; YAML-NEXT: MajorVersion: 6
+; YAML-NEXT: MinorVersion: 5
+; YAML-NEXT: ShaderKind: 6
+; YAML-NEXT: Size: [[#div(DXILSIZE,4)]]
+; YAML-NEXT: DXILMajorVersion: 1
+; YAML-NEXT: DXILMinorVersion: 5
+; YAML-NEXT: DXILSize: [[#DXILSIZE - 24]]
+; YAML-NEXT: DXIL: [ 0x42, 0x43, 0xC0, 0xDE,
+
+; Check that ILDB has the debug info, and DXIL does not:
+
+; ILDB-DIS: define i32 @add(i32 %a, i32 %b)
+; ILDB-DIS: !llvm.dbg.cu
+; ILDB-DIS: !DICompileUnit
+; ILDB-DIS: !DIFile
+; ILDB-DIS: !"Dwarf Version"
+; ILDB-DIS: !"Debug Info Version"
+
+; DXIL-DIS: define i32 @add(i32 %a, i32 %b)
+; 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: "hlsl.hlsl"
diff --git a/llvm/test/tools/dxil-dis/dbg-declare-undef.ll b/llvm/test/tools/dxil-dis/dbg-declare-undef.ll
index fa599ea02d912..e816f44c2e7df 100644
--- a/llvm/test/tools/dxil-dis/dbg-declare-undef.ll
+++ b/llvm/test/tools/dxil-dis/dbg-declare-undef.ll
@@ -1,4 +1,6 @@
-; RUN: llc --filetype=obj %s -o - | dxil-dis -o - | FileCheck %s
+; RUN: llc --filetype=obj %s -o %t.dxbc
+; RUN: llvm-objcopy --dump-section=ILDB=%t.bc %t.dxbc
+; RUN: dxil-dis %t.bc -o - | FileCheck %s
target triple = "dxil-pc-shadermodel6.3-library"
diff --git a/llvm/test/tools/dxil-dis/dbg-value.ll b/llvm/test/tools/dxil-dis/dbg-value.ll
index 51dc2fa968efa..64f62e34e6b5f 100644
--- a/llvm/test/tools/dxil-dis/dbg-value.ll
+++ b/llvm/test/tools/dxil-dis/dbg-value.ll
@@ -1,4 +1,6 @@
-; RUN: llc --filetype=obj %s -o - | dxil-dis -o - | FileCheck %s
+; RUN: llc --filetype=obj %s -o %t.dxbc
+; RUN: llvm-objcopy --dump-section=ILDB=%t.bc %t.dxbc
+; RUN: dxil-dis %t.bc -o - | FileCheck %s
target triple = "dxil-pc-shadermodel6.3-library"
diff --git a/llvm/test/tools/dxil-dis/debug-info.ll b/llvm/test/tools/dxil-dis/debug-info.ll
index 783c652f5df0a..ba4a0adb6e5b2 100644
--- a/llvm/test/tools/dxil-dis/debug-info.ll
+++ b/llvm/test/tools/dxil-dis/debug-info.ll
@@ -1,4 +1,6 @@
-; RUN: llc --filetype=obj %s -o - | dxil-dis -o - | FileCheck %s
+; RUN: llc --filetype=obj %s -o %t.dxbc
+; RUN: llvm-objcopy --dump-section=ILDB=%t.bc %t.dxbc
+; RUN: dxil-dis %t.bc -o - | FileCheck %s
target triple = "dxil-unknown-shadermodel6.7-library"
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
diff --git a/llvm/test/tools/dxil-dis/di-compile-unit-versioned-language.ll b/llvm/test/tools/dxil-dis/di-compile-unit-versioned-language.ll
index 42c469acfd810..4ac9fa17477b9 100644
--- a/llvm/test/tools/dxil-dis/di-compile-unit-versioned-language.ll
+++ b/llvm/test/tools/dxil-dis/di-compile-unit-versioned-language.ll
@@ -1,4 +1,6 @@
-; RUN: llc --filetype=obj %s -o - | dxil-dis -o - | FileCheck %s
+; RUN: llc --filetype=obj %s -o %t.dxbc
+; RUN: llvm-objcopy --dump-section=ILDB=%t.bc %t.dxbc
+; RUN: dxil-dis %t.bc -o - | FileCheck %s
target triple = "dxil-unknown-shadermodel6.3-library"
diff --git a/llvm/test/tools/dxil-dis/di-compile-unit.ll b/llvm/test/tools/dxil-dis/di-compile-unit.ll
index 10988fc3defe4..c080a6b05e678 100644
--- a/llvm/test/tools/dxil-dis/di-compile-unit.ll
+++ b/llvm/test/tools/dxil-dis/di-compile-unit.ll
@@ -1,4 +1,6 @@
-; RUN: llc --filetype=obj %s -o - | dxil-dis -o - | FileCheck %s
+; RUN: llc --filetype=obj %s -o %t.dxbc
+; RUN: llvm-objcopy --dump-section=ILDB=%t.bc %t.dxbc
+; RUN: dxil-dis %t.bc -o - | FileCheck %s
target triple = "dxil-unknown-shadermodel6.7-library"
!llvm.dbg.cu = !{!0}
diff --git a/llvm/test/tools/dxil-dis/di-label.ll b/llvm/test/tools/dxil-dis/di-label.ll
index 7b66ba8ec4893..43a6377ec89d0 100644
--- a/llvm/test/tools/dxil-dis/di-label.ll
+++ b/llvm/test/tools/dxil-dis/di-label.ll
@@ -1,4 +1,6 @@
-; RUN: llc --filetype=obj %s -o - | dxil-dis -o - | FileCheck %s
+; RUN: llc --filetype=obj %s -o %t.dxbc
+; RUN: llvm-objcopy --dump-section=ILDB=%t.bc %t.dxbc
+; RUN: dxil-dis %t.bc -o - | FileCheck %s
target triple = "dxil-pc-shadermodel6.3-library"
diff --git a/llvm/test/tools/dxil-dis/di-subprogram.ll b/llvm/test/tools/dxil-dis/di-subprogram.ll
index 9d31b611e71df..aed4690a38e26 100644
--- a/llvm/test/tools/dxil-dis/di-subprogram.ll
+++ b/llvm/test/tools/dxil-dis/di-subprogram.ll
@@ -1,4 +1,6 @@
-; RUN: llc --filetype=obj %s -o - | dxil-dis -o - | FileCheck %s
+; RUN: llc --filetype=obj %s -o %t.dxbc
+; RUN: llvm-objcopy --dump-section=ILDB=%t.bc %t.dxbc
+; RUN: dxil-dis %t.bc -o - | FileCheck %s
target triple = "dxil-unknown-shadermodel6.7-library"
define float @fmaf(float %x, float %y, float %z) !dbg !4 {
diff --git a/llvm/test/tools/dxil-dis/di-subrange.ll b/llvm/test/tools/dxil-dis/di-subrange.ll
index 5141fe509d647..339410e7b6eb3 100644
--- a/llvm/test/tools/dxil-dis/di-subrange.ll
+++ b/llvm/test/tools/dxil-dis/di-subrange.ll
@@ -1,4 +1,6 @@
-; RUN: llc --filetype=obj %s -o - | dxil-dis -o - | FileCheck %s
+; RUN: llc --filetype=obj %s -o %t.dxbc
+; RUN: llvm-objcopy --dump-section=ILDB=%t.bc %t.dxbc
+; RUN: dxil-dis %t.bc -o - | FileCheck %s
target triple = "dxil-unknown-shadermodel6.7-library"
!llvm.module.flags = !{!0, !1}
diff --git a/llvm/test/tools/dxil-dis/di-subrangetype.ll b/llvm/test/tools/dxil-dis/di-subrangetype.ll
index cb81a9d072f31..5d2601ea00da8 100644
--- a/llvm/test/tools/dxil-dis/di-subrangetype.ll
+++ b/llvm/test/tools/dxil-dis/di-subrangetype.ll
@@ -1,4 +1,6 @@
-; RUN: llc --filetype=obj %s -o - | dxil-dis -o - | FileCheck %s
+; RUN: llc --filetype=obj %s -o %t.dxbc
+; RUN: llvm-objcopy --dump-section=ILDB=%t.bc %t.dxbc
+; RUN: dxil-dis %t.bc -o - | FileCheck %s
target triple = "dxil-pc-shadermodel6.3-library"
diff --git a/llvm/test/tools/dxil-dis/vla.ll b/llvm/test/tools/dxil-dis/vla.ll
index 2287999d134cc..491cea0626862 100644
--- a/llvm/test/tools/dxil-dis/vla.ll
+++ b/llvm/test/tools/dxil-dis/vla.ll
@@ -1,4 +1,6 @@
-; RUN: llc --filetype=obj %s -o - | dxil-dis -o - | FileCheck %s
+; RUN: llc --filetype=obj %s -o %t.dxbc
+; RUN: llvm-objcopy --dump-section=ILDB=%t.bc %t.dxbc
+; RUN: dxil-dis %t.bc -o - | FileCheck %s
target triple = "dxil-pc-shadermodel6.3-library"
>From c2581e782dfb001f056203b8a114c80fdcb89cb0 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Wed, 3 Jun 2026 22:50:23 +0500
Subject: [PATCH 2/3] Add an assert for when the module has some debug info,
but no compile units.
---
llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp
index 6b249a5b309e5..e78e6775403fa 100644
--- a/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp
+++ b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp
@@ -187,6 +187,13 @@ class EmbedDXILPass : public llvm::ModulePass {
if (NMD.getName().starts_with("dx.source"))
NMD.eraseFromParent();
}
+ } else {
+#ifdef EXPENSIVE_CHECKS
+ assert(
+ StripDebugInfo(M) == false &&
+ "The module must not contain any debug info here."
+ "Shader modules with debug info must have !DICompileUnit metadata.");
+#endif
}
const auto DIMap = DXILDebugInfoPass::run(M);
WriteDXILToFile(M, OS, DIMap);
>From eaa16e4b548b8d63844ba1e9a7443ada3cf517dc Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Mon, 8 Jun 2026 15:35:56 +0500
Subject: [PATCH 3/3] Fix a new test after rebasing
---
llvm/test/tools/dxil-dis/di-globalvariable.ll | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/llvm/test/tools/dxil-dis/di-globalvariable.ll b/llvm/test/tools/dxil-dis/di-globalvariable.ll
index effa606b81283..ed864cccc4354 100644
--- a/llvm/test/tools/dxil-dis/di-globalvariable.ll
+++ b/llvm/test/tools/dxil-dis/di-globalvariable.ll
@@ -1,4 +1,6 @@
-; RUN: llc --filetype=obj %s -o - | dxil-dis -o - | FileCheck %s
+; RUN: llc --filetype=obj %s -o %t.dxbc
+; RUN: llvm-objcopy --dump-section=ILDB=%t.bc %t.dxbc
+; RUN: dxil-dis %t.bc -o - | FileCheck %s
target triple = "dxil-unknown-shadermodel6.3-library"
More information about the llvm-commits
mailing list