[llvm] [DirectX][NFC] Delay converting to old-style debug info (PR #201336)
Harald van Dijk via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 4 06:44:28 PDT 2026
https://github.com/hvdijk updated https://github.com/llvm/llvm-project/pull/201336
>From 67e9d95206d34270dd6c428d8d8352174ceae293 Mon Sep 17 00:00:00 2001
From: Harald van Dijk <hdijk at accesssoftek.com>
Date: Mon, 18 May 2026 15:13:04 +0100
Subject: [PATCH 1/8] [NFC] Add AAW::emitMDNodeAnnot
Similarly to the other AAW::emit*Annot functions, this may be used to
emit a comment before a metadata node.
---
llvm/include/llvm/IR/AssemblyAnnotationWriter.h | 5 +++++
llvm/lib/IR/AsmWriter.cpp | 3 +++
2 files changed, 8 insertions(+)
diff --git a/llvm/include/llvm/IR/AssemblyAnnotationWriter.h b/llvm/include/llvm/IR/AssemblyAnnotationWriter.h
index d68bcbf85b2b7..bcc5244c0b93e 100644
--- a/llvm/include/llvm/IR/AssemblyAnnotationWriter.h
+++ b/llvm/include/llvm/IR/AssemblyAnnotationWriter.h
@@ -23,6 +23,7 @@ namespace llvm {
class Function;
class BasicBlock;
class Instruction;
+class MDNode;
class Value;
class formatted_raw_ostream;
@@ -53,6 +54,10 @@ class LLVM_ABI AssemblyAnnotationWriter {
virtual void emitInstructionAnnot(const Instruction *,
formatted_raw_ostream &) {}
+ /// emitMDNodeAnnot - This may be implemented to emit a string right before a
+ /// metadata node is emitted.
+ virtual void emitMDNodeAnnot(const MDNode *, formatted_raw_ostream &) {}
+
/// printInfoComment - This may be implemented to emit a comment to the
/// right of an instruction or global value.
virtual void printInfoComment(const Value &, formatted_raw_ostream &) {}
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 106fd6541360c..af27a19caaa81 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -4978,6 +4978,9 @@ void AssemblyWriter::printMetadataAttachments(
}
void AssemblyWriter::writeMDNode(unsigned Slot, const MDNode *Node) {
+ if (AnnotationWriter)
+ AnnotationWriter->emitMDNodeAnnot(Node, Out);
+
Out << '!' << Slot << " = ";
printMDNodeBody(Node);
Out << "\n";
>From 1e2b554ea328c8e64dfec0ba6d94c034e236d0df Mon Sep 17 00:00:00 2001
From: Harald van Dijk <hdijk at accesssoftek.com>
Date: Mon, 18 May 2026 15:51:41 +0100
Subject: [PATCH 2/8] [DirectX] Move IR printing to DXILPrettyPrinter
By doing the IR printing inside DXILPrettyPrinter, we have the option to
customise what we print and include the info that we collect and
generate in DXILDebugInfo.
---
llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp | 100 ++++++++++++++++--
.../Target/DirectX/DirectXTargetMachine.cpp | 1 -
.../di-compile-unit-versioned-language.ll | 15 +++
.../DirectX/DebugInfo/di-subprogram.ll | 57 ++++++++++
llvm/test/CodeGen/DirectX/llc-pipeline.ll | 3 +-
5 files changed, 166 insertions(+), 10 deletions(-)
create mode 100755 llvm/test/CodeGen/DirectX/DebugInfo/di-compile-unit-versioned-language.ll
create mode 100755 llvm/test/CodeGen/DirectX/DebugInfo/di-subprogram.ll
diff --git a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
index 12e54ad2cc73e..1758be83a01dc 100644
--- a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
@@ -8,16 +8,24 @@
#include "DXILPrettyPrinter.h"
#include "DirectX.h"
+#include "DirectXIRPasses/DXILDebugInfo.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/DXILResource.h"
+#include "llvm/IR/AssemblyAnnotationWriter.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/ModuleSlotTracker.h"
#include "llvm/IR/PassManager.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
+using namespace llvm::dxil;
static StringRef getRCName(dxil::ResourceClass RC) {
switch (RC) {
@@ -251,12 +259,91 @@ static void prettyPrintResources(raw_ostream &OS, const DXILResourceMap &DRM,
OS << ";\n";
}
+namespace {
+class DXILAssemblyAnnotationWriter : public llvm::AssemblyAnnotationWriter {
+private:
+ ModuleSlotTracker &MST;
+ AbstractSlotTrackerStorage &STS;
+ const DXILDebugInfoMap &DI;
+
+public:
+ DXILAssemblyAnnotationWriter(ModuleSlotTracker &MST,
+ AbstractSlotTrackerStorage &STS,
+ const DXILDebugInfoMap &DI)
+ : MST(MST), STS(STS), DI(DI) {}
+
+ void emitMDNodeAnnot(const MDNode *N,
+ formatted_raw_ostream &os) override {
+ if (auto *NewMD = DI.MDReplace.lookup(N)) {
+ if (auto *NewN = dyn_cast<MDNode>(NewMD))
+ if (STS.getMetadataSlot(NewN) == -1)
+ STS.createMetadataSlot(NewN);
+
+ os << "; DXIL: ";
+ N->printAsOperand(os, MST);
+ os << ": to be replaced by: ";
+ NewMD->printAsOperand(os, MST);
+ os << "\n";
+ return;
+ }
+
+ if (auto *ExtraMD = DI.MDExtra.lookup(N)) {
+ if (auto *ExtraN = dyn_cast<MDNode>(ExtraMD))
+ if (STS.getMetadataSlot(ExtraN) == -1)
+ STS.createMetadataSlot(ExtraN);
+
+ os << "; DXIL: ";
+ N->printAsOperand(os, MST);
+ os << ": additional data: ";
+ ExtraMD->printAsOperand(os, MST);
+ os << "\n";
+ return;
+ }
+ }
+};
+} // namespace
+
+static void prettyPrint(raw_ostream &OS, Module &M, const DXILResourceMap &DRM,
+ DXILResourceTypeMap &DRTM) {
+ formatted_raw_ostream FOS(OS);
+
+ prettyPrintResources(FOS, DRM, DRTM);
+
+ auto DI = DXILDebugInfoPass::run(M);
+
+ ModuleSlotTracker MST(&M);
+ AbstractSlotTrackerStorage *STS = nullptr;
+ unsigned NextMetadataSlot = 0;
+ MST.setProcessHook(
+ [&](AbstractSlotTrackerStorage *STS_, const Module *, bool) {
+ STS = STS_;
+ NextMetadataSlot = STS->getNextMetadataSlot();
+ });
+ // Force initialisation. ModuleSlotTracker does not have a dedicated function
+ // for this so trigger it through a dummy print.
+ MDNode::get(M.getContext(), {})->print(llvm::nulls(), MST);
+ assert(STS && "Slot tracker storage should have been initialised");
+
+ DXILAssemblyAnnotationWriter DAAW(MST, *STS, DI);
+ M.print(FOS, &DAAW);
+
+ ModuleSlotTracker::MachineMDNodeListType MDNodes;
+ MST.collectMDNodes(MDNodes, NextMetadataSlot, ~0u);
+ std::sort(MDNodes.begin(), MDNodes.end(),
+ [](auto &A, auto &B) { return A.first < B.first; });
+ for (auto [_, MDNode] : MDNodes) {
+ DAAW.emitMDNodeAnnot(MDNode, FOS);
+ MDNode->print(FOS, MST);
+ FOS << "\n";
+ }
+}
+
PreservedAnalyses DXILPrettyPrinterPass::run(Module &M,
ModuleAnalysisManager &MAM) {
const DXILResourceMap &DRM = MAM.getResult<DXILResourceAnalysis>(M);
DXILResourceTypeMap &DRTM = MAM.getResult<DXILResourceTypeAnalysis>(M);
- prettyPrintResources(OS, DRM, DRTM);
- return PreservedAnalyses::all();
+ prettyPrint(OS, M, DRM, DRTM);
+ return PreservedAnalyses::none();
}
namespace {
@@ -269,12 +356,11 @@ class DXILPrettyPrinterLegacy : public llvm::ModulePass {
explicit DXILPrettyPrinterLegacy(raw_ostream &O) : ModulePass(ID), OS(O) {}
StringRef getPassName() const override {
- return "DXIL Metadata Pretty Printer";
+ return "DXIL Pretty Printer";
}
bool runOnModule(Module &M) override;
void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
AU.addRequired<DXILResourceTypeWrapperPass>();
AU.addRequired<DXILResourceWrapperPass>();
}
@@ -283,18 +369,18 @@ class DXILPrettyPrinterLegacy : public llvm::ModulePass {
char DXILPrettyPrinterLegacy::ID = 0;
INITIALIZE_PASS_BEGIN(DXILPrettyPrinterLegacy, "dxil-pretty-printer",
- "DXIL Metadata Pretty Printer", true, true)
+ "DXIL Pretty Printer", true, true)
INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass)
INITIALIZE_PASS_END(DXILPrettyPrinterLegacy, "dxil-pretty-printer",
- "DXIL Metadata Pretty Printer", true, true)
+ "DXIL Pretty Printer", true, true)
bool DXILPrettyPrinterLegacy::runOnModule(Module &M) {
const DXILResourceMap &DRM =
getAnalysis<DXILResourceWrapperPass>().getResourceMap();
DXILResourceTypeMap &DRTM =
getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();
- prettyPrintResources(OS, DRM, DRTM);
+ prettyPrint(OS, M, DRM, DRTM);
return false;
}
diff --git a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
index 234385828bd3d..583cfa96df5a5 100644
--- a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
+++ b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
@@ -165,7 +165,6 @@ bool DirectXTargetMachine::addPassesToEmitFile(
switch (FileType) {
case CodeGenFileType::AssemblyFile:
PM.add(createDXILPrettyPrinterLegacyPass(Out));
- PM.add(createPrintModulePass(Out, "", true));
break;
case CodeGenFileType::ObjectFile:
if (TargetPassConfig::willCompleteCodeGenPipeline()) {
diff --git a/llvm/test/CodeGen/DirectX/DebugInfo/di-compile-unit-versioned-language.ll b/llvm/test/CodeGen/DirectX/DebugInfo/di-compile-unit-versioned-language.ll
new file mode 100755
index 0000000000000..bcf27509deaa5
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/DebugInfo/di-compile-unit-versioned-language.ll
@@ -0,0 +1,15 @@
+; RUN: llc --filetype=asm %s -o - | FileCheck %s
+
+target triple = "dxil-unknown-shadermodel6.3-library"
+
+;; CHECK-DAG: [[CU:![0-9]+]] = distinct !DICompileUnit(sourceLanguageName: DW_LNAME_C, sourceLanguageVersion: 199901,
+;; CHECK-DAG: DXIL: [[CU]]: to be replaced by: [[NEWCU:![0-9]+]]
+;; CHECK-DAG: [[NEWCU]] = distinct !DICompileUnit(language: DW_LANG_C99,
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3}
+
+!0 = distinct !DICompileUnit(sourceLanguageName: DW_LNAME_C, sourceLanguageVersion: 199901, file: !1, isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
+!1 = !DIFile(filename: "versioned-language.c", directory: "")
+!2 = !{i32 7, !"Dwarf Version", i32 6}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
diff --git a/llvm/test/CodeGen/DirectX/DebugInfo/di-subprogram.ll b/llvm/test/CodeGen/DirectX/DebugInfo/di-subprogram.ll
new file mode 100755
index 0000000000000..47291c447ff83
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/DebugInfo/di-subprogram.ll
@@ -0,0 +1,57 @@
+; RUN: llc --filetype=asm %s -o - | FileCheck %s
+target triple = "dxil-unknown-shadermodel6.7-library"
+
+define float @fmaf(float %x, float %y, float %z) !dbg !4 {
+ unreachable
+}
+
+declare !dbg !14 double @fma(double %x, double %y, double %z)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!12, !13}
+!llvm.used = !{!5}
+
+; CHECK: DXIL: !0: additional data: !16
+; CHECK: !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Some Compiler", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Some Compiler", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
+; CHECK: !1 = !DIFile(filename: "some-source", directory: "some-path")
+!1 = !DIFile(filename: "some-source", directory: "some-path")
+!2 = !{}
+
+; CHECK: !3 = !{i32 2, !"Dwarf Version", i32 4}
+; CHECK: !4 = !{i32 2, !"Debug Info Version", i32 3}
+
+; CHECK: DXIL: !8: additional data: ptr @fmaf
+; CHECK: !8 = distinct !DISubprogram(name: "fmaf", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
+!4 = distinct !DISubprogram(name: "fmaf", scope: !1, file: !1, line: 1, type: !5, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
+
+; CHECK: !9 = !DISubroutineType(types: !10)
+!5 = !DISubroutineType(types: !6)
+
+; CHECK: !10 = !{!11, !11, !11, !11}
+!6 = !{!7, !7, !7, !7}
+
+; CHECK: !11 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
+!7 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
+
+; CHECK: !12 = !{!13, !14, !15}
+!8 = !{!9, !10, !11}
+
+; CHECK: !13 = !DILocalVariable(name: "x", arg: 1, scope: !8, file: !1, line: 1, type: !11)
+!9 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !1, line: 1, type: !7)
+
+; CHECK: !14 = !DILocalVariable(name: "y", arg: 2, scope: !8, file: !1, line: 1, type: !11)
+!10 = !DILocalVariable(name: "y", arg: 2, scope: !4, file: !1, line: 1, type: !7)
+
+; CHECK: !15 = !DILocalVariable(name: "z", arg: 3, scope: !8, file: !1, line: 1, type: !11)
+!11 = !DILocalVariable(name: "z", arg: 3, scope: !4, file: !1, line: 1, type: !7)
+
+!12 = !{i32 2, !"Dwarf Version", i32 4}
+!13 = !{i32 2, !"Debug Info Version", i32 3}
+
+!14 = !DISubprogram(name: "fma", scope: !1, file: !1, line: 1, type: !15, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized)
+!15 = !DISubroutineType(types: !16)
+!16 = !{!17, !17, !17, !17}
+!17 = !DIBasicType(name: "double", size: 64, encoding: DW_ATE_float)
+
+; CHECK: !16 = !{!8}
diff --git a/llvm/test/CodeGen/DirectX/llc-pipeline.ll b/llvm/test/CodeGen/DirectX/llc-pipeline.ll
index 2474e08ac1549..8f8c9fbde794d 100644
--- a/llvm/test/CodeGen/DirectX/llc-pipeline.ll
+++ b/llvm/test/CodeGen/DirectX/llc-pipeline.ll
@@ -50,8 +50,7 @@
; CHECK-NEXT: DXIL Op Lowering
; CHECK-NEXT: DXIL Prepare Module
-; CHECK-ASM-NEXT: DXIL Metadata Pretty Printer
-; CHECK-ASM-NEXT: Print Module IR
+; CHECK-ASM-NEXT: DXIL Pretty Printer
; CHECK-OBJ-NEXT: DXIL Embedder
; CHECK-OBJ-NEXT: DXContainer Global Emitter
>From 154d7f2c3739fb560d0615a9c41773ffd4792195 Mon Sep 17 00:00:00 2001
From: Harald van Dijk <hdijk at accesssoftek.com>
Date: Mon, 18 May 2026 16:16:53 +0100
Subject: [PATCH 3/8] clang-format
---
llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
index 1758be83a01dc..d4b0469f2db62 100644
--- a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
@@ -272,8 +272,7 @@ class DXILAssemblyAnnotationWriter : public llvm::AssemblyAnnotationWriter {
const DXILDebugInfoMap &DI)
: MST(MST), STS(STS), DI(DI) {}
- void emitMDNodeAnnot(const MDNode *N,
- formatted_raw_ostream &os) override {
+ void emitMDNodeAnnot(const MDNode *N, formatted_raw_ostream &os) override {
if (auto *NewMD = DI.MDReplace.lookup(N)) {
if (auto *NewN = dyn_cast<MDNode>(NewMD))
if (STS.getMetadataSlot(NewN) == -1)
@@ -355,9 +354,7 @@ class DXILPrettyPrinterLegacy : public llvm::ModulePass {
explicit DXILPrettyPrinterLegacy(raw_ostream &O) : ModulePass(ID), OS(O) {}
- StringRef getPassName() const override {
- return "DXIL Pretty Printer";
- }
+ StringRef getPassName() const override { return "DXIL Pretty Printer"; }
bool runOnModule(Module &M) override;
void getAnalysisUsage(AnalysisUsage &AU) const override {
>From 69e298db7516dd39ee1358c5550c6209fef5535e Mon Sep 17 00:00:00 2001
From: Harald van Dijk <hdijk at accesssoftek.com>
Date: Wed, 20 May 2026 03:23:49 +0100
Subject: [PATCH 4/8] Reduce use of auto.
---
llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
index d4b0469f2db62..3c2f60a0099ec 100644
--- a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
@@ -273,8 +273,8 @@ class DXILAssemblyAnnotationWriter : public llvm::AssemblyAnnotationWriter {
: MST(MST), STS(STS), DI(DI) {}
void emitMDNodeAnnot(const MDNode *N, formatted_raw_ostream &os) override {
- if (auto *NewMD = DI.MDReplace.lookup(N)) {
- if (auto *NewN = dyn_cast<MDNode>(NewMD))
+ if (const Metadata *NewMD = DI.MDReplace.lookup(N)) {
+ if (const auto *NewN = dyn_cast<MDNode>(NewMD))
if (STS.getMetadataSlot(NewN) == -1)
STS.createMetadataSlot(NewN);
@@ -286,8 +286,8 @@ class DXILAssemblyAnnotationWriter : public llvm::AssemblyAnnotationWriter {
return;
}
- if (auto *ExtraMD = DI.MDExtra.lookup(N)) {
- if (auto *ExtraN = dyn_cast<MDNode>(ExtraMD))
+ if (const Metadata *ExtraMD = DI.MDExtra.lookup(N)) {
+ if (const auto *ExtraN = dyn_cast<MDNode>(ExtraMD))
if (STS.getMetadataSlot(ExtraN) == -1)
STS.createMetadataSlot(ExtraN);
@@ -308,7 +308,7 @@ static void prettyPrint(raw_ostream &OS, Module &M, const DXILResourceMap &DRM,
prettyPrintResources(FOS, DRM, DRTM);
- auto DI = DXILDebugInfoPass::run(M);
+ DXILDebugInfoMap DI = DXILDebugInfoPass::run(M);
ModuleSlotTracker MST(&M);
AbstractSlotTrackerStorage *STS = nullptr;
@@ -328,8 +328,10 @@ static void prettyPrint(raw_ostream &OS, Module &M, const DXILResourceMap &DRM,
ModuleSlotTracker::MachineMDNodeListType MDNodes;
MST.collectMDNodes(MDNodes, NextMetadataSlot, ~0u);
- std::sort(MDNodes.begin(), MDNodes.end(),
- [](auto &A, auto &B) { return A.first < B.first; });
+ std::sort(
+ MDNodes.begin(), MDNodes.end(),
+ [](std::pair<unsigned, const MDNode *> &A,
+ std::pair<unsigned, const MDNode *> &B) { return A.first < B.first; });
for (auto [_, MDNode] : MDNodes) {
DAAW.emitMDNodeAnnot(MDNode, FOS);
MDNode->print(FOS, MST);
>From 480a6e01fd8a7939267e8a44760fdff65b32b258 Mon Sep 17 00:00:00 2001
From: Harald van Dijk <hdijk at accesssoftek.com>
Date: Thu, 21 May 2026 01:34:38 +0100
Subject: [PATCH 5/8] Adjust test after merged PRs.
---
llvm/test/CodeGen/DirectX/DebugInfo/di-subprogram.ll | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/DirectX/DebugInfo/di-subprogram.ll b/llvm/test/CodeGen/DirectX/DebugInfo/di-subprogram.ll
index 47291c447ff83..fd73830985e12 100755
--- a/llvm/test/CodeGen/DirectX/DebugInfo/di-subprogram.ll
+++ b/llvm/test/CodeGen/DirectX/DebugInfo/di-subprogram.ll
@@ -21,7 +21,7 @@ declare !dbg !14 double @fma(double %x, double %y, double %z)
; CHECK: !3 = !{i32 2, !"Dwarf Version", i32 4}
; CHECK: !4 = !{i32 2, !"Debug Info Version", i32 3}
-; CHECK: DXIL: !8: additional data: ptr @fmaf
+; CHECK: DXIL: !8: to be replaced by: !17
; CHECK: !8 = distinct !DISubprogram(name: "fmaf", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
!4 = distinct !DISubprogram(name: "fmaf", scope: !1, file: !1, line: 1, type: !5, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
@@ -55,3 +55,6 @@ declare !dbg !14 double @fma(double %x, double %y, double %z)
!17 = !DIBasicType(name: "double", size: 64, encoding: DW_ATE_float)
; CHECK: !16 = !{!8}
+
+; CHECK: DXIL: !17: additional data: ptr @fmaf
+; CHECK: !17 = !DISubprogram(name: "fmaf", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
>From 919025005c298a5e51d7b018ca5af70d99f4eb19 Mon Sep 17 00:00:00 2001
From: Harald van Dijk <hdijk at accesssoftek.com>
Date: Thu, 28 May 2026 20:23:11 +0100
Subject: [PATCH 6/8] Update after #197478
---
llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp | 9 +++++++++
llvm/test/CodeGen/DirectX/debug-info.ll | 9 ++++++---
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
index 3c2f60a0099ec..f6268735127d4 100644
--- a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
@@ -272,6 +272,15 @@ class DXILAssemblyAnnotationWriter : public llvm::AssemblyAnnotationWriter {
const DXILDebugInfoMap &DI)
: MST(MST), STS(STS), DI(DI) {}
+ void emitInstructionAnnot(const Instruction *OrigI,
+ formatted_raw_ostream &os) override {
+ if (const Instruction *I = &DI.getDXILInstruction(*OrigI); I != OrigI) {
+ os << "; DXIL: to be replaced with: ";
+ I->print(os, MST);
+ os << "\n";
+ }
+ }
+
void emitMDNodeAnnot(const MDNode *N, formatted_raw_ostream &os) override {
if (const Metadata *NewMD = DI.MDReplace.lookup(N)) {
if (const auto *NewN = dyn_cast<MDNode>(NewMD))
diff --git a/llvm/test/CodeGen/DirectX/debug-info.ll b/llvm/test/CodeGen/DirectX/debug-info.ll
index b9cff28290d6a..e78b5ab5547aa 100644
--- a/llvm/test/CodeGen/DirectX/debug-info.ll
+++ b/llvm/test/CodeGen/DirectX/debug-info.ll
@@ -8,9 +8,12 @@ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
; CHECK: define dso_local float @fma(float %0, float %1, float %2) local_unnamed_addr #0 !dbg [[Fn:[!][0-9]+]]
define dso_local float @fma(float %0, float %1, float %2) local_unnamed_addr #0 !dbg !6 {
-; CHECK-NEXT: call void @llvm.dbg.value(metadata float %0, metadata [[VarX:[!][0-9]+]], metadata !DIExpression()), !dbg [[Line1:[!][0-9]+]]
-; CHECK-NEXT: call void @llvm.dbg.value(metadata float %1, metadata [[VarY:[!][0-9]+]], metadata !DIExpression()), !dbg [[Line1]]
-; CHECK-NEXT: call void @llvm.dbg.value(metadata float %2, metadata [[VarZ:[!][0-9]+]], metadata !DIExpression()), !dbg [[Line1]]
+; CHECK-NEXT: DXIL: to be replaced with: tail call addrspace(0) void @llvm.dbg.value(metadata float %0, i64 0, metadata [[VarX:[!][0-9]+]], metadata !DIExpression()), !dbg [[Line1:[!][0-9]+]]
+; CHECK-NEXT: call void @llvm.dbg.value(metadata float %0, metadata [[VarX]], metadata !DIExpression()), !dbg [[Line1]]
+; CHECK-NEXT: DXIL: to be replaced with: tail call addrspace(0) void @llvm.dbg.value(metadata float %1, i64 0, metadata [[VarY:[!][0-9]+]], metadata !DIExpression()), !dbg [[Line1]]
+; CHECK-NEXT: call void @llvm.dbg.value(metadata float %1, metadata [[VarY]], metadata !DIExpression()), !dbg [[Line1]]
+; CHECK-NEXT: DXIL: to be replaced with: tail call addrspace(0) void @llvm.dbg.value(metadata float %2, i64 0, metadata [[VarZ:[!][0-9]+]], metadata !DIExpression()), !dbg [[Line1]]
+; CHECK-NEXT: call void @llvm.dbg.value(metadata float %2, metadata [[VarZ]], metadata !DIExpression()), !dbg [[Line1]]
call void @llvm.dbg.value(metadata float %0, metadata !11, metadata !DIExpression()), !dbg !14
call void @llvm.dbg.value(metadata float %1, metadata !12, metadata !DIExpression()), !dbg !14
call void @llvm.dbg.value(metadata float %2, metadata !13, metadata !DIExpression()), !dbg !14
>From 9838854b753c9c4cbb60468794d5b70970b94ff4 Mon Sep 17 00:00:00 2001
From: Harald van Dijk <hdijk at accesssoftek.com>
Date: Thu, 28 May 2026 20:24:48 +0100
Subject: [PATCH 7/8] Make sort comparator accept const values
---
llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
index f6268735127d4..d28a2ef1095f8 100644
--- a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
@@ -337,10 +337,11 @@ static void prettyPrint(raw_ostream &OS, Module &M, const DXILResourceMap &DRM,
ModuleSlotTracker::MachineMDNodeListType MDNodes;
MST.collectMDNodes(MDNodes, NextMetadataSlot, ~0u);
- std::sort(
- MDNodes.begin(), MDNodes.end(),
- [](std::pair<unsigned, const MDNode *> &A,
- std::pair<unsigned, const MDNode *> &B) { return A.first < B.first; });
+ std::sort(MDNodes.begin(), MDNodes.end(),
+ [](const std::pair<unsigned, const MDNode *> &A,
+ const std::pair<unsigned, const MDNode *> &B) {
+ return A.first < B.first;
+ });
for (auto [_, MDNode] : MDNodes) {
DAAW.emitMDNodeAnnot(MDNode, FOS);
MDNode->print(FOS, MST);
>From 67f62403427919d636fd0f17d5752955a3bfe26e Mon Sep 17 00:00:00 2001
From: Harald van Dijk <hdijk at accesssoftek.com>
Date: Wed, 3 Jun 2026 00:57:34 +0100
Subject: [PATCH 8/8] [DirectX][NFC] Delay converting to old-style debug info
This is NFC at the moment, but upcoming work relies on debug info still
using new-style debug records after DXILPrepare.
---
llvm/lib/Target/DirectX/DXILPrepare.cpp | 121 ++++++++++--------
llvm/lib/Target/DirectX/DirectX.h | 4 +
.../DirectX/DirectXIRPasses/DXILDebugInfo.cpp | 10 ++
3 files changed, 79 insertions(+), 56 deletions(-)
diff --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp
index 81f4d3da48362..7aafc926a5c5a 100644
--- a/llvm/lib/Target/DirectX/DXILPrepare.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp
@@ -33,55 +33,71 @@
using namespace llvm;
using namespace llvm::dxil;
-namespace {
-
-constexpr bool isValidForDXIL(Attribute::AttrKind Attr) {
- return is_contained({Attribute::Alignment,
- Attribute::AlwaysInline,
- Attribute::Builtin,
- Attribute::ByVal,
- Attribute::InAlloca,
- Attribute::Cold,
- Attribute::Convergent,
- Attribute::InlineHint,
- Attribute::InReg,
- Attribute::JumpTable,
- Attribute::MinSize,
- Attribute::Naked,
- Attribute::Nest,
- Attribute::NoAlias,
- Attribute::NoBuiltin,
- Attribute::NoDuplicate,
- Attribute::NoImplicitFloat,
- Attribute::NoInline,
- Attribute::NonLazyBind,
- Attribute::NonNull,
- Attribute::Dereferenceable,
- Attribute::DereferenceableOrNull,
- Attribute::Memory,
- Attribute::NoRedZone,
- Attribute::NoReturn,
- Attribute::NoUnwind,
- Attribute::OptimizeForSize,
- Attribute::OptimizeNone,
- Attribute::ReadNone,
- Attribute::ReadOnly,
- Attribute::Returned,
- Attribute::ReturnsTwice,
- Attribute::SExt,
- Attribute::StackAlignment,
- Attribute::StackProtect,
- Attribute::StackProtectReq,
- Attribute::StackProtectStrong,
- Attribute::SafeStack,
- Attribute::StructRet,
- Attribute::SanitizeAddress,
- Attribute::SanitizeThread,
- Attribute::SanitizeMemory,
- Attribute::UWTable,
- Attribute::ZExt},
- Attr);
+namespace llvm {
+namespace dxil {
+const AttributeMask &getNonDXILAttributeMask() {
+ static const AttributeMask Result = [] {
+ AttributeMask DXILAttributeMask;
+ for (Attribute::AttrKind Kind : {Attribute::Alignment,
+ Attribute::AlwaysInline,
+ Attribute::Builtin,
+ Attribute::ByVal,
+ Attribute::InAlloca,
+ Attribute::Cold,
+ Attribute::Convergent,
+ Attribute::InlineHint,
+ Attribute::InReg,
+ Attribute::JumpTable,
+ Attribute::MinSize,
+ Attribute::Naked,
+ Attribute::Nest,
+ Attribute::NoAlias,
+ Attribute::NoBuiltin,
+ Attribute::NoDuplicate,
+ Attribute::NoImplicitFloat,
+ Attribute::NoInline,
+ Attribute::NonLazyBind,
+ Attribute::NonNull,
+ Attribute::Dereferenceable,
+ Attribute::DereferenceableOrNull,
+ Attribute::Memory,
+ Attribute::NoRedZone,
+ Attribute::NoReturn,
+ Attribute::NoUnwind,
+ Attribute::OptimizeForSize,
+ Attribute::OptimizeNone,
+ Attribute::ReadNone,
+ Attribute::ReadOnly,
+ Attribute::Returned,
+ Attribute::ReturnsTwice,
+ Attribute::SExt,
+ Attribute::StackAlignment,
+ Attribute::StackProtect,
+ Attribute::StackProtectReq,
+ Attribute::StackProtectStrong,
+ Attribute::SafeStack,
+ Attribute::StructRet,
+ Attribute::SanitizeAddress,
+ Attribute::SanitizeThread,
+ Attribute::SanitizeMemory,
+ Attribute::UWTable,
+ Attribute::ZExt})
+ DXILAttributeMask.addAttribute(Kind);
+ AttributeMask Result;
+ for (Attribute::AttrKind Kind = Attribute::None;
+ Kind != Attribute::EndAttrKinds;
+ Kind = Attribute::AttrKind(Kind + 1)) {
+ if (!DXILAttributeMask.contains(Kind))
+ Result.addAttribute(Kind);
+ }
+ return Result;
+ }();
+ return Result;
}
+} // namespace dxil
+} // namespace llvm
+
+namespace {
static void collectDeadStringAttrs(AttributeMask &DeadAttrs, AttributeSet &&AS,
const StringSet<> &LiveKeys,
@@ -177,15 +193,8 @@ class DXILPrepareModule : public ModulePass {
public:
bool runOnModule(Module &M) override {
- M.convertFromNewDbgValues();
-
PointerTypeMap PointerTypes = PointerTypeAnalysis::run(M);
- AttributeMask AttrMask;
- for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds;
- I = Attribute::AttrKind(I + 1)) {
- if (!isValidForDXIL(I))
- AttrMask.addAttribute(I);
- }
+ const AttributeMask &AttrMask = getNonDXILAttributeMask();
const dxil::ModuleMetadataInfo MetadataInfo =
getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();
diff --git a/llvm/lib/Target/DirectX/DirectX.h b/llvm/lib/Target/DirectX/DirectX.h
index dfeb1ab12665d..3aa91ca75dd4b 100644
--- a/llvm/lib/Target/DirectX/DirectX.h
+++ b/llvm/lib/Target/DirectX/DirectX.h
@@ -12,6 +12,7 @@
#define LLVM_LIB_TARGET_DIRECTX_DIRECTX_H
namespace llvm {
+class AttributeMask;
class FunctionPass;
class ModulePass;
class PassRegistry;
@@ -126,6 +127,9 @@ void initializeDXILFinalizeLinkageLegacyPass(PassRegistry &);
/// Pass to finalize linkage of functions.
ModulePass *createDXILFinalizeLinkageLegacyPass();
+namespace dxil {
+const AttributeMask &getNonDXILAttributeMask();
+} // namespace dxil
} // namespace llvm
#endif // LLVM_LIB_TARGET_DIRECTX_DIRECTX_H
diff --git a/llvm/lib/Target/DirectX/DirectXIRPasses/DXILDebugInfo.cpp b/llvm/lib/Target/DirectX/DirectXIRPasses/DXILDebugInfo.cpp
index 0fa81186000f9..7ccf46ab9239e 100644
--- a/llvm/lib/Target/DirectX/DirectXIRPasses/DXILDebugInfo.cpp
+++ b/llvm/lib/Target/DirectX/DirectXIRPasses/DXILDebugInfo.cpp
@@ -7,7 +7,9 @@
//===----------------------------------------------------------------------===//
#include "DXILDebugInfo.h"
+#include "DirectX.h"
#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/IR/AttributeMask.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicsDirectX.h"
@@ -64,11 +66,19 @@ static void replaceDbgValue(Module &M, DXILDebugInfoMap &Res) {
}
DXILDebugInfoMap DXILDebugInfoPass::run(Module &M) {
+ M.convertFromNewDbgValues();
+
DXILDebugInfoMap Res;
DebugInfoFinder DIF;
DIF.processModule(M);
+ const AttributeMask &AttrMask = getNonDXILAttributeMask();
for (auto &F : M) {
+ F.removeFnAttrs(AttrMask);
+ F.removeRetAttrs(AttrMask);
+ for (unsigned ArgNo = 0; ArgNo != F.arg_size(); ++ArgNo)
+ F.removeParamAttrs(ArgNo, AttrMask);
+
for (auto &BB : F) {
for (auto &I : make_early_inc_range(reverse(BB))) {
if (auto *DL = dyn_cast<DbgLabelInst>(&I)) {
More information about the llvm-commits
mailing list