[llvm] [DebugInfo] Robustify DISubprogram upgrade (PR #190611)
Harald van Dijk via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 6 07:26:50 PDT 2026
https://github.com/hvdijk created https://github.com/llvm/llvm-project/pull/190611
The bitcode upgrade process for DISubprogram was fragile and depended on the exact order in which DICompileUnit, DISubprogram, and the list of DISubprograms were emitted. This would work out okay with bitcode written by standard LLVM, but was not a rule that the old format had. This commit makes the upgrade process work when these metadata nodes are emitted in any order, and updates the existing upgrade-subprogram.ll test to cover all orders. The corresponding .bc file was written by a patched version of LLVM 3.7 that provides a hook to force nodes to be emitted in a specific order and can be inspected with llvm-bcanalyzer --dump.
>From 44581623114768ce693bb24980b31b9c0fa0c91f Mon Sep 17 00:00:00 2001
From: Harald van Dijk <hdijk at accesssoftek.com>
Date: Tue, 24 Mar 2026 21:53:50 +0000
Subject: [PATCH] [DebugInfo] Robustify DISubprogram upgrade
The bitcode upgrade process for DISubprogram was fragile and depended on
the exact order in which DICompileUnit, DISubprogram, and the list of
DISubprograms were emitted. This would work out okay with bitcode
written by standard LLVM, but was not a rule that the old format had.
This commit makes the upgrade process work when these metadata nodes are
emitted in any order, and updates the existing upgrade-subprogram.ll
test to cover all orders. The corresponding .bc file was written by a
patched version of LLVM 3.7 that provides a hook to force nodes to be
emitted in a specific order and can be inspected with
llvm-bcanalyzer --dump.
---
llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 14 ++--
llvm/test/Bitcode/upgrade-subprogram.ll | 74 ++++++++++++++++++---
llvm/test/Bitcode/upgrade-subprogram.ll.bc | Bin 784 -> 1080 bytes
3 files changed, 71 insertions(+), 17 deletions(-)
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index 4bc55232a6df6..aac380330b681 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -446,7 +446,7 @@ class MetadataLoader::MetadataLoaderImpl {
// Keep mapping of seens pair of old-style CU <-> SP, and update pointers to
// point from SP to CU after a block is completly parsed.
- std::vector<std::pair<DICompileUnit *, Metadata *>> CUSubprograms;
+ std::vector<std::pair<DICompileUnit *, unsigned>> CUSubprograms;
/// Functions that need to be matched with subprograms when upgrading old
/// metadata.
@@ -485,7 +485,8 @@ class MetadataLoader::MetadataLoaderImpl {
/// Upgrade old-style CU <-> SP pointers to point from SP to CU.
void upgradeCUSubprograms() {
for (auto CU_SP : CUSubprograms)
- if (auto *SPs = dyn_cast_or_null<MDTuple>(CU_SP.second))
+ if (auto *SPs =
+ dyn_cast_or_null<MDTuple>(MetadataList.lookup(CU_SP.second - 1)))
for (auto &Op : SPs->operands())
if (auto *SP = dyn_cast_or_null<DISubprogram>(Op))
SP->replaceUnit(CU_SP.first);
@@ -1333,11 +1334,6 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
return getMD(ID - 1);
return nullptr;
};
- auto getMDOrNullWithoutPlaceholders = [&](unsigned ID) -> Metadata * {
- if (ID)
- return MetadataList.getMetadataFwdRef(ID - 1);
- return nullptr;
- };
auto getMDString = [&](unsigned ID) -> MDString * {
// This requires that the ID is not really a forward reference. In
// particular, the MDString must already have been resolved.
@@ -1959,8 +1955,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
NextMetadataNo++;
// Move the Upgrade the list of subprograms.
- if (Metadata *SPs = getMDOrNullWithoutPlaceholders(Record[11]))
- CUSubprograms.push_back({CU, SPs});
+ if (Record[11])
+ CUSubprograms.push_back({CU, Record[11]});
break;
}
case bitc::METADATA_SUBPROGRAM: {
diff --git a/llvm/test/Bitcode/upgrade-subprogram.ll b/llvm/test/Bitcode/upgrade-subprogram.ll
index fb807ed6daaf0..a9a5399c7fa97 100644
--- a/llvm/test/Bitcode/upgrade-subprogram.ll
+++ b/llvm/test/Bitcode/upgrade-subprogram.ll
@@ -1,17 +1,75 @@
; RUN: llvm-dis < %s.bc | FileCheck %s
; RUN: verify-uselistorder < %s.bc
-; CHECK: define void @foo() !dbg [[SP:![0-9]+]]
-define void @foo() {
+; CHECK: define void @fooCLS() !dbg [[CLSSP:![0-9]+]]
+define void @fooCLS() {
+ ret void
+}
+
+; CHECK: define void @fooCSL() !dbg [[CSLSP:![0-9]+]]
+define void @fooCSL() {
+ ret void
+}
+
+; CHECK: define void @fooLCS() !dbg [[LCSSP:![0-9]+]]
+define void @fooLCS() {
+ ret void
+}
+
+; CHECK: define void @fooLSC() !dbg [[LSCSP:![0-9]+]]
+define void @fooLSC() {
+ ret void
+}
+
+; CHECK: define void @fooSCL() !dbg [[SCLSP:![0-9]+]]
+define void @fooSCL() {
+ ret void
+}
+
+; CHECK: define void @fooSLC() !dbg [[SLCSP:![0-9]+]]
+define void @fooSLC() {
ret void
}
!llvm.module.flags = !{!0}
!0 = !{i32 2, !"Debug Info Version", i32 3}
-!llvm.dbg.cu = !{!1}
-!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, emissionKind: FullDebug)
-!2 = !DIFile(filename: "foo.c", directory: "/path/to/dir")
-; CHECK: [[SP]] = distinct !DISubprogram
-!3 = distinct !DISubprogram(file: !2, scope: !2, line: 51, name: "foo", function: void ()* @foo, type: !4)
-!4 = !DISubroutineType(types: !{})
+!llvm.dbg.cu = !{!3, !6, !10, !14, !16, !20}
+!1 = !DIFile(filename: "foo.c", directory: "/path/to/dir")
+!2 = !DISubroutineType(types: !{})
+
+; CHECK-DAG: [[CLSSP]] = distinct !DISubprogram{{.*}}, unit: [[CLSCU:![0-9]+]]
+; CHECK-DAG: [[CLSCU]] = distinct !DICompileUnit
+!3 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, subprograms: !4, emissionKind: 1)
+!4 = !{!5}
+!5 = !DISubprogram(file: !1, scope: !2, line: 51, name: "fooCLS", function: void ()* @fooCLS, type: !2)
+
+; CHECK-DAG: [[CSLSP]] = distinct !DISubprogram{{.*}}, unit: [[CSLCU:![0-9]+]]
+; CHECK-DAG: [[CSLCU]] = distinct !DICompileUnit
+!6 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, subprograms: !8, emissionKind: 1)
+!7 = !DISubprogram(file: !1, scope: !2, line: 51, name: "fooCSL", function: void ()* @fooCSL, type: !2)
+!8 = !{!7}
+
+; CHECK-DAG: [[LCSSP]] = distinct !DISubprogram{{.*}}, unit: [[LCSCU:![0-9]+]]
+; CHECK-DAG: [[LCSCU]] = distinct !DICompileUnit
+!9 = !{!11}
+!10 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, subprograms: !9, emissionKind: 1)
+!11 = !DISubprogram(file: !1, scope: !2, line: 51, name: "fooLCS", function: void ()* @fooLCS, type: !2)
+
+; CHECK-DAG: [[LSCSP]] = distinct !DISubprogram{{.*}}, unit: [[LSCCU:![0-9]+]]
+; CHECK-DAG: [[LSCCU]] = distinct !DICompileUnit
+!12 = !{!13}
+!13 = !DISubprogram(file: !1, scope: !2, line: 51, name: "fooLSC", function: void ()* @fooLSC, type: !2)
+!14 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, subprograms: !12, emissionKind: 1)
+
+; CHECK-DAG: [[SCLSP]] = distinct !DISubprogram{{.*}}, unit: [[SCLCU:![0-9]+]]
+; CHECK-DAG: [[SCLCU]] = distinct !DICompileUnit
+!15 = !DISubprogram(file: !1, scope: !2, line: 51, name: "fooSCL", function: void ()* @fooSCL, type: !2)
+!16 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, subprograms: !17, emissionKind: 1)
+!17 = !{!15}
+
+; CHECK-DAG: [[SLCSP]] = distinct !DISubprogram{{.*}}, unit: [[SLCCU:![0-9]+]]
+; CHECK-DAG: [[SLCCU]] = distinct !DICompileUnit
+!18 = !DISubprogram(file: !1, scope: !2, line: 51, name: "fooSLC", function: void ()* @fooSLC, type: !2)
+!19 = !{!18}
+!20 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, subprograms: !19, emissionKind: 1)
diff --git a/llvm/test/Bitcode/upgrade-subprogram.ll.bc b/llvm/test/Bitcode/upgrade-subprogram.ll.bc
index cfab5a2c76a9814c8324d6cece8bf7172fc1ea65..814296e7e2799be7890d84265d7d34bd4f5e053e 100644
GIT binary patch
delta 681
zcmbQhwu6Jq$@#!NMIHtQZpMjfv+LVz7#ZMzr;-WIW{~*Ag5VfD;Y4r}P6#774q_ZY
z4l58F$;}Xu6!e+U!>Q(ejKw)ga0(+sr33>*I#5oE)8_(9qk)*mk^sI(0sPMy*j7H^
zd-j2^J|ThosRIA!34HG#@Cma#x?#X_Xu|@7_VNmLbBT7=Gtvi~EiN!y?P0Xtb69$U
zv(<^i3m7$ecn>UNWS9`>e?SIkv;)v93=Gmt>5Yke??3P at KESovz)_$fRCt2H0Yi39
z0iY5F2WEx?E7TMCfJ_C322O?s);7yMhpl at K)$43H#Nx;i=Ig-3cw9yWXciC%f{e>_
zZs at IIdIsV%F)UzUh)9 at m*m at 7McF!Rl9|4xct1K#F1!o+Yz+qIt$gn~2ftUo)L+?S>
za|yE~Mwl{ovdI)rU;u}24g*6E+_V!g(+=y at _b_P#jY|R=CkHp~10#dME6y3rK&v?z
z9Dq at EL!jXx(_xu=4`tIDMcopc6hv05DM&Iun9<Av3VenJu$n0c;a+4g1_}yF&yJn#
zeOo$GHhN~aWb}=jccvsfICL!S`ZFiBvS&tN=0`nbc)FOGfoj3=<g~ewk%O at wXl<ba
zI7}Jb5=8nA7cCW)XnnjvHJ!ojp+(HesD?lbzT?x>fKtIlYj}ZDQ*_vYCL{v&fV?Wq
L!pKAk8yuhjsDPw=
delta 382
zcmdnNF at a6Z$@#!NQxOIRRt5%!Bpw45pU8dB-hQ^z4LvKs1QcRW<Y8dg#W0a;cD;%j
zhsYJ6vJ*^<AjL*<GdLs#eJ1p9s<|IyaZVDP!pKl5!N8ybl#^oinc&7GY~rZE<mHl@
zRGO~fnU|KY5SCh0oSB~|%;I#zfaTDELvP-mP3<|u9U~!oi~H_v?#Nkp7BFh?@TKMF
zOE>s3GpGo&Fh-cNvNOpPFJNGF1i40sfgy)uMxg%z86d}jfq|ESq4&m(H at 9ML-8=E>
z#;KSyHx8Y9wv5GD+{|pZnYhtL<LMiBX*x249Tv8EEfWW0{b8Qtne7D;?L`I6B^m4$
z3GF2k?IjD^CC>%(zhmJ46u|dn0^ef?{)Y;DZvyy?6*Oe;9F#lcD0fLw=1!yBod+^c
z9?HIAluMHcwAkQmHK*Ac=#WGO1_nkT4RkM4A&|`uWC!sHD5W$lkx_6t at x;T at p<}{A
PraNprt&cf?a$o=ec;a<l
More information about the llvm-commits
mailing list