[llvm] [RemoveDIs] Auto-upgrade debug intrinsics to DbgRecords (default false) (PR #85650)
Orlando Cazalet-Hyams via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 18 08:06:08 PDT 2024
https://github.com/OCHyams created https://github.com/llvm/llvm-project/pull/85650
If --load-bitcode-into-experimental-debuginfo-iterators is true then debug
intrinsics are auto-upgraded to DbgRecords (the new debug info format).
The upgrade is trivial because the two representations are semantically
identical. llvm.dbg.value with 4 operands and llvm.dbg.addr intrinsics are
upgraded in the same way as usual, but converted directly into DbgRecords
instead of debug intrinsics.
---
Note: this patch depends on #85649 -- please only review the **second commit** (I will rebase once the other patch lands on main).
>From be4fb65bf0155f1423ca8be1be909247b27aff1e Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Mon, 18 Mar 2024 13:09:14 +0000
Subject: [PATCH 1/2] [RemoveDIs] Add flag to control loading into new debug
mode from bitcode
--load-bitcode-into-experimental-debuginfo-iterators
false: Convert to the old debug mode after reading.
true: Upgrade to the new debug info format (*).
unset: Same as false (for now).
(*) As of this patch it actually just means "don't convert to either mode after
loading". Auto-upgrading will be implemented in an upcoming patch.
With this flag we can incrementally add support for RemoveDIs by overriding
the "unset" behaviour in individual tools.
---
llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 22 +++++++++++-----
llvm/test/Bitcode/dbg-record-roundtrip.ll | 31 ++++++++++++++++++++++-
llvm/tools/llvm-dis/llvm-dis.cpp | 10 +++++++-
3 files changed, 55 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index d284c9823c9ede..a375cafe53d4f6 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -100,6 +100,13 @@ static cl::opt<bool> ExpandConstantExprs(
cl::desc(
"Expand constant expressions to instructions for testing purposes"));
+/// Load bitcode directly into RemoveDIs format (use debug records instead
+/// of debug intrinsics). UNSET is treated as FALSE, so the default action
+/// is to do nothing. Individual tools can override this to incrementally add
+/// support for the RemoveDIs format.
+cl::opt<cl::boolOrDefault> LoadBitcodeIntoNewDbgInforFormat(
+ "load-bitcode-into-experimental-debuginfo-iterators", cl::Hidden);
+
namespace {
enum {
@@ -4276,9 +4283,11 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
Error BitcodeReader::parseModule(uint64_t ResumeBit,
bool ShouldLazyLoadMetadata,
ParserCallbacks Callbacks) {
- // Force the debug-info mode into the old format for now.
- // FIXME: Remove this once all tools support RemoveDIs.
- TheModule->IsNewDbgInfoFormat = false;
+ // Load directly into RemoveDIs format if LoadBitcodeIntoNewDbgInforFormat
+ // has been set to true (default action: load into the old debug format).
+ TheModule->IsNewDbgInfoFormat =
+ UseNewDbgInfoFormat &&
+ LoadBitcodeIntoNewDbgInforFormat == cl::boolOrDefault::BOU_TRUE;
this->ValueTypeCallback = std::move(Callbacks.ValueType);
if (ResumeBit) {
@@ -6762,9 +6771,9 @@ Error BitcodeReader::materialize(GlobalValue *GV) {
if (Error JumpFailed = Stream.JumpToBit(DFII->second))
return JumpFailed;
- // Set the debug info mode to "new", forcing a mismatch between
+ // Set the debug info mode to "new", possibly creating a mismatch between
// module and function debug modes. This is okay because we'll convert
- // everything back to the old mode after parsing.
+ // everything back to the old mode after parsing if needed.
// FIXME: Remove this once all tools support RemoveDIs.
F->IsNewDbgInfoFormat = true;
@@ -6774,7 +6783,8 @@ Error BitcodeReader::materialize(GlobalValue *GV) {
// Convert new debug info records into intrinsics.
// FIXME: Remove this once all tools support RemoveDIs.
- F->convertFromNewDbgValues();
+ if (!F->getParent()->IsNewDbgInfoFormat)
+ F->convertFromNewDbgValues();
if (StripDebugInfo)
stripDebugInfo(*F);
diff --git a/llvm/test/Bitcode/dbg-record-roundtrip.ll b/llvm/test/Bitcode/dbg-record-roundtrip.ll
index 84606b589e8830..251c3d9f4bb7e0 100644
--- a/llvm/test/Bitcode/dbg-record-roundtrip.ll
+++ b/llvm/test/Bitcode/dbg-record-roundtrip.ll
@@ -1,5 +1,15 @@
;; Roundtrip tests.
-; RUN: llvm-as --write-experimental-debuginfo-iterators-to-bitcode=true %s -o - | llvm-dis | FileCheck %s
+
+;; Load RemoveDIs mode in llvm-dis but write out debug intrinsics.
+; RUN: llvm-as --write-experimental-debuginfo-iterators-to-bitcode=true %s -o - \
+; RUN: | llvm-dis --load-bitcode-into-experimental-debuginfo-iterators=true --write-experimental-debuginfo=false \
+; RUN: | FileCheck %s
+
+;; Load and write RemoveDIs mode in llvm-dis.
+; RUN: llvm-as --write-experimental-debuginfo-iterators-to-bitcode=true %s -o - \
+; RUN: | llvm-dis --load-bitcode-into-experimental-debuginfo-iterators=true --write-experimental-debuginfo=true \
+; RUN: | FileCheck %s --check-prefixes=RECORDS
+
;; Check that verify-uselistorder passes regardless of input format.
; RUN: llvm-as %s --write-experimental-debuginfo-iterators-to-bitcode=true -o - | verify-uselistorder
; RUN: verify-uselistorder %s
@@ -39,16 +49,24 @@ entry:
; CHECK-NEXT: dbg.value(metadata ![[empty:[0-9]+]], metadata ![[e]], metadata !DIExpression()), !dbg ![[dbg]]
; CHECK-NEXT: dbg.value(metadata i32 poison, metadata ![[e]], metadata !DIExpression()), !dbg ![[dbg]]
; CHECK-NEXT: dbg.value(metadata i32 1, metadata ![[f:[0-9]+]], metadata !DIExpression()), !dbg ![[dbg]]
+; RECORDS: entry:
+; RECORDS-NEXT: dbg_value(i32 %p, ![[e:[0-9]+]], !DIExpression(), ![[dbg:[0-9]+]])
+; RECORDS-NEXT: dbg_value(![[empty:[0-9]+]], ![[e]], !DIExpression(), ![[dbg]])
+; RECORDS-NEXT: dbg_value(i32 poison, ![[e]], !DIExpression(), ![[dbg]])
+; RECORDS-NEXT: dbg_value(i32 1, ![[f:[0-9]+]], !DIExpression(), ![[dbg]])
tail call void @llvm.dbg.value(metadata i32 %p, metadata !32, metadata !DIExpression()), !dbg !19
tail call void @llvm.dbg.value(metadata !29, metadata !32, metadata !DIExpression()), !dbg !19
tail call void @llvm.dbg.value(metadata i32 poison, metadata !32, metadata !DIExpression()), !dbg !19
tail call void @llvm.dbg.value(metadata i32 1, metadata !33, metadata !DIExpression()), !dbg !19
;; Arglist with an argument, constant, local use before def, poison.
; CHECK-NEXT: dbg.value(metadata !DIArgList(i32 %p, i32 0, i32 %0, i32 poison), metadata ![[f]], metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_arg, 2, DW_OP_LLVM_arg, 3, DW_OP_plus, DW_OP_minus)), !dbg ![[dbg]]
+; RECORDS-NEXT: dbg_value(!DIArgList(i32 %p, i32 0, i32 %0, i32 poison), ![[f]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_arg, 2, DW_OP_LLVM_arg, 3, DW_OP_plus, DW_OP_minus), ![[dbg]])
tail call void @llvm.dbg.value(metadata !DIArgList(i32 %p, i32 0, i32 %0, i32 poison), metadata !33, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_arg, 2, DW_OP_LLVM_arg, 3, DW_OP_plus, DW_OP_minus)), !dbg !19
;; Check dbg.assign use before def (value, addr and ID). Check expression order too.
; CHECK: dbg.assign(metadata i32 %0, metadata ![[i:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, 0),
; CHECK-SAME: metadata ![[ID:[0-9]+]], metadata ptr %a, metadata !DIExpression(DW_OP_plus_uconst, 1)), !dbg ![[dbg]]
+; RECORDS: dbg_assign(i32 %0, ![[i:[0-9]+]], !DIExpression(DW_OP_plus_uconst, 0),
+; RECORDS-SAME: ![[ID:[0-9]+]], ptr %a, !DIExpression(DW_OP_plus_uconst, 1), ![[dbg]])
tail call void @llvm.dbg.assign(metadata i32 %0, metadata !36, metadata !DIExpression(DW_OP_plus_uconst, 0), metadata !37, metadata ptr %a, metadata !DIExpression(DW_OP_plus_uconst, 1)), !dbg !19
%a = alloca i32, align 4, !DIAssignID !37
; CHECK: %a = alloca i32, align 4, !DIAssignID ![[ID]]
@@ -58,6 +76,13 @@ entry:
; CHECK-NEXT: dbg.declare(metadata ptr poison, metadata ![[c:[0-9]+]], metadata !DIExpression()), !dbg ![[dbg]]
; CHECK-NEXT: dbg.declare(metadata ptr null, metadata ![[d:[0-9]+]], metadata !DIExpression()), !dbg ![[dbg]]
; CHECK-NEXT: dbg.declare(metadata ptr @g, metadata ![[h:[0-9]+]], metadata !DIExpression()), !dbg ![[dbg]]
+; RECORDS: %a = alloca i32, align 4, !DIAssignID ![[ID]]
+;; Check dbg.declare configurations.
+; RECORDS-NEXT: dbg_declare(ptr %a, ![[a:[0-9]+]], !DIExpression(), ![[dbg]])
+; RECORDS-NEXT: dbg_declare(![[empty:[0-9]+]], ![[b:[0-9]+]], !DIExpression(), ![[dbg]])
+; RECORDS-NEXT: dbg_declare(ptr poison, ![[c:[0-9]+]], !DIExpression(), ![[dbg]])
+; RECORDS-NEXT: dbg_declare(ptr null, ![[d:[0-9]+]], !DIExpression(), ![[dbg]])
+; RECORDS-NEXT: dbg_declare(ptr @g, ![[h:[0-9]+]], !DIExpression(), ![[dbg]])
tail call void @llvm.dbg.declare(metadata ptr %a, metadata !17, metadata !DIExpression()), !dbg !19
tail call void @llvm.dbg.declare(metadata !29, metadata !28, metadata !DIExpression()), !dbg !19
tail call void @llvm.dbg.declare(metadata ptr poison, metadata !30, metadata !DIExpression()), !dbg !19
@@ -65,17 +90,21 @@ entry:
tail call void @llvm.dbg.declare(metadata ptr @g, metadata !35, metadata !DIExpression()), !dbg !19
;; Argument value dbg.declare.
; CHECK: dbg.declare(metadata ptr %storage, metadata ![[g:[0-9]+]], metadata !DIExpression()), !dbg ![[dbg]]
+; RECORDS: dbg_declare(ptr %storage, ![[g:[0-9]+]], !DIExpression(), ![[dbg]])
tail call void @llvm.dbg.declare(metadata ptr %storage, metadata !34, metadata !DIExpression()), !dbg !19
;; Use before def dbg.value.
; CHECK: dbg.value(metadata i32 %0, metadata ![[e]], metadata !DIExpression()), !dbg ![[dbg]]
+; RECORDS: dbg_value(i32 %0, ![[e]], !DIExpression(), ![[dbg]])
tail call void @llvm.dbg.value(metadata i32 %0, metadata !32, metadata !DIExpression()), !dbg !19
%0 = load i32, ptr @g, align 4, !dbg !20
;; Non-argument local value dbg.value.
; CHECK: dbg.value(metadata i32 %0, metadata ![[e]], metadata !DIExpression()), !dbg ![[dbg]]
+; RECORDS: dbg_value(i32 %0, ![[e]], !DIExpression(), ![[dbg]])
tail call void @llvm.dbg.value(metadata i32 %0, metadata !32, metadata !DIExpression()), !dbg !19
store i32 %0, ptr %a, align 4, !dbg !19
%1 = load i32, ptr %a, align 4, !dbg !25
; CHECK: dbg.label(metadata ![[label:[0-9]+]]), !dbg ![[dbg]]
+; RECORDS: dbg_label(![[label:[0-9]+]], ![[dbg]])
tail call void @llvm.dbg.label(metadata !38), !dbg !19
ret i32 %1, !dbg !27
}
diff --git a/llvm/tools/llvm-dis/llvm-dis.cpp b/llvm/tools/llvm-dis/llvm-dis.cpp
index 06fc669390bf1d..8e443318dd7d2c 100644
--- a/llvm/tools/llvm-dis/llvm-dis.cpp
+++ b/llvm/tools/llvm-dis/llvm-dis.cpp
@@ -80,6 +80,8 @@ static cl::opt<bool> PrintThinLTOIndexOnly(
cl::desc("Only read thinlto index and print the index as LLVM assembly."),
cl::init(false), cl::Hidden, cl::cat(DisCategory));
+extern cl::opt<bool> WriteNewDbgInfoFormat;
+
namespace {
static void printDebugLoc(const DebugLoc &DL, formatted_raw_ostream &OS) {
@@ -249,8 +251,14 @@ int main(int argc, char **argv) {
// All that llvm-dis does is write the assembly to a file.
if (!DontPrint) {
- if (M)
+ if (M) {
+ bool ChangeDbgFormat = M->IsNewDbgInfoFormat != WriteNewDbgInfoFormat;
+ if (ChangeDbgFormat)
+ M->setIsNewDbgInfoFormat(WriteNewDbgInfoFormat);
M->print(Out->os(), Annotator.get(), PreserveAssemblyUseListOrder);
+ if (ChangeDbgFormat)
+ M->setIsNewDbgInfoFormat(!WriteNewDbgInfoFormat);
+ }
if (Index)
Index->print(Out->os());
}
>From e4566042f502b501a4880e13079e4c675b25c4ca Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Mon, 18 Mar 2024 14:16:59 +0000
Subject: [PATCH 2/2] [RemoveDIs] Auto-upgrade debug intrinsics to DbgRecords
(default false)
If --load-bitcode-into-experimental-debuginfo-iterators is true then debug
intrinsics are auto-upgraded to DbgRecords (the new debug info format).
The upgrade is trivial because the two representations are semantically
identical. llvm.dbg.value with 4 operands and llvm.dbg.addr intrinsics are
upgraded in the same way as usual, but converted directly into DbgRecords
instead of debug intrinsics.
---
llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 26 +++++---
llvm/lib/IR/AutoUpgrade.cpp | 70 ++++++++++++++++++++-
llvm/test/Bitcode/DIExpression-aggresult.ll | 1 +
llvm/test/Bitcode/dbg-record-roundtrip.ll | 5 ++
llvm/test/Bitcode/upgrade-dbg-addr.ll | 1 +
5 files changed, 93 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index 770eb83af17f9b..115ac75c1c32ad 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -609,17 +609,25 @@ class MetadataLoader::MetadataLoaderImpl {
if (!NeedDeclareExpressionUpgrade)
return;
+ auto UpdateDeclareIfNeeded = [&](auto *Declare) {
+ auto *DIExpr = Declare->getExpression();
+ if (!DIExpr || !DIExpr->startsWithDeref() ||
+ !isa_and_nonnull<Argument>(Declare->getAddress()))
+ return;
+ SmallVector<uint64_t, 8> Ops;
+ Ops.append(std::next(DIExpr->elements_begin()), DIExpr->elements_end());
+ Declare->setExpression(DIExpression::get(Context, Ops));
+ };
+
for (auto &BB : F)
- for (auto &I : BB)
+ for (auto &I : BB) {
+ for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) {
+ if (DPV.isDbgDeclare())
+ UpdateDeclareIfNeeded(&DPV);
+ }
if (auto *DDI = dyn_cast<DbgDeclareInst>(&I))
- if (auto *DIExpr = DDI->getExpression())
- if (DIExpr->startsWithDeref() &&
- isa_and_nonnull<Argument>(DDI->getAddress())) {
- SmallVector<uint64_t, 8> Ops;
- Ops.append(std::next(DIExpr->elements_begin()),
- DIExpr->elements_end());
- DDI->setExpression(DIExpression::get(Context, Ops));
- }
+ UpdateDeclareIfNeeded(DDI);
+ }
}
/// Upgrade the expression from previous versions.
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index be0abb4b71dae2..c18ef45e1284b1 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -1052,6 +1052,18 @@ static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
}
case 'd':
if (Name.consume_front("dbg.")) {
+ // Mark debug intrinsics for upgrade to new debug format.
+ if (F->getParent()->IsNewDbgInfoFormat) {
+ if (Name == "addr" || Name == "value" || Name == "assign" ||
+ Name == "declare" || Name == "label") {
+ // There's no function to replace these with.
+ NewFn = nullptr;
+ // But we do want these to get upgraded.
+ return true;
+ }
+ }
+ // Update llvm.dbg.addr intrinsics even in "new debug mode"; they'll get
+ // converted to DPValues later.
if (Name == "addr" || (Name == "value" && F->arg_size() == 4)) {
rename(F);
NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::dbg_value);
@@ -2328,6 +2340,59 @@ static Value *upgradeAMDGCNIntrinsicCall(StringRef Name, CallBase *CI,
llvm_unreachable("Unknown function for AMDGPU intrinsic upgrade.");
}
+/// Helper to unwrap intrinsic call MetadataAsValue operands.
+template <typename MDType>
+static MDType *unwrapMAVOp(CallBase *CI, unsigned Op) {
+ if (MetadataAsValue *MAV = dyn_cast<MetadataAsValue>(CI->getArgOperand(Op)))
+ return dyn_cast<MDType>(MAV->getMetadata());
+ return nullptr;
+}
+
+/// Convert debug intrinsic calls to non-instruction debug records.
+/// \p Name - Final part of the intrinsic name, e.g. 'value' in llvm.dbg.value.
+/// \p CI - The debug intrinsic call.
+static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) {
+ DbgRecord *DR = nullptr;
+ if (Name == "label") {
+ DR = new DPLabel(unwrapMAVOp<DILabel>(CI, 0), CI->getDebugLoc());
+ } else if (Name == "assign") {
+ DR = new DPValue(
+ unwrapMAVOp<Metadata>(CI, 0), unwrapMAVOp<DILocalVariable>(CI, 1),
+ unwrapMAVOp<DIExpression>(CI, 2), unwrapMAVOp<DIAssignID>(CI, 3),
+ unwrapMAVOp<Metadata>(CI, 4), unwrapMAVOp<DIExpression>(CI, 5),
+ CI->getDebugLoc());
+ } else if (Name == "declare") {
+ DR = new DPValue(unwrapMAVOp<Metadata>(CI, 0),
+ unwrapMAVOp<DILocalVariable>(CI, 1),
+ unwrapMAVOp<DIExpression>(CI, 2), CI->getDebugLoc(),
+ DPValue::LocationType::Declare);
+ } else if (Name == "addr") {
+ // Upgrade dbg.addr to dbg.value with DW_OP_deref.
+ DIExpression *Expr = unwrapMAVOp<DIExpression>(CI, 2);
+ Expr = DIExpression::append(Expr, dwarf::DW_OP_deref);
+ DR = new DPValue(unwrapMAVOp<Metadata>(CI, 0),
+ unwrapMAVOp<DILocalVariable>(CI, 1), Expr,
+ CI->getDebugLoc());
+ } else if (Name == "value") {
+ // An old version of dbg.value had an extra offset argument.
+ unsigned VarOp = 1;
+ unsigned ExprOp = 2;
+ if (CI->arg_size() == 4) {
+ auto *Offset = dyn_cast_or_null<Constant>(CI->getArgOperand(1));
+ // Nonzero offset dbg.values get dropped without a replacement.
+ if (!Offset || !Offset->isZeroValue())
+ return;
+ VarOp = 2;
+ ExprOp = 3;
+ }
+ DR = new DPValue(unwrapMAVOp<Metadata>(CI, 0),
+ unwrapMAVOp<DILocalVariable>(CI, VarOp),
+ unwrapMAVOp<DIExpression>(CI, ExprOp), CI->getDebugLoc());
+ }
+ assert(DR && "Unhandled intrinsic kind in upgrade to DbgRecord");
+ CI->getParent()->insertDbgRecordBefore(DR, CI->getIterator());
+}
+
/// Upgrade a call to an old intrinsic. All argument and return casting must be
/// provided to seamlessly integrate with existing context.
void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) {
@@ -2353,6 +2418,7 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) {
bool IsNVVM = Name.consume_front("nvvm.");
bool IsARM = Name.consume_front("arm.");
bool IsAMDGCN = Name.consume_front("amdgcn.");
+ bool IsDbg = Name.consume_front("dbg.");
if (IsX86 && Name.starts_with("sse4a.movnt.")) {
SmallVector<Metadata *, 1> Elts;
@@ -2457,7 +2523,7 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) {
return;
}
- Value *Rep;
+ Value *Rep = nullptr;
// Upgrade packed integer vector compare intrinsics to compare instructions.
if (IsX86 && (Name.starts_with("sse2.pcmp") ||
Name.starts_with("avx2.pcmp"))) {
@@ -4192,6 +4258,8 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) {
Rep = upgradeARMIntrinsicCall(Name, CI, F, Builder);
} else if (IsAMDGCN) {
Rep = upgradeAMDGCNIntrinsicCall(Name, CI, F, Builder);
+ } else if (IsDbg && CI->getModule()->IsNewDbgInfoFormat) {
+ upgradeDbgIntrinsicToDbgRecord(Name, CI);
} else {
llvm_unreachable("Unknown function for CallBase upgrade.");
}
diff --git a/llvm/test/Bitcode/DIExpression-aggresult.ll b/llvm/test/Bitcode/DIExpression-aggresult.ll
index 0b89454aa2f942..017218277d02bf 100644
--- a/llvm/test/Bitcode/DIExpression-aggresult.ll
+++ b/llvm/test/Bitcode/DIExpression-aggresult.ll
@@ -1,4 +1,5 @@
; RUN: llvm-dis -o - %s.bc | FileCheck %s
+; RUN: llvm-dis -o - %s.bc --load-bitcode-into-experimental-debuginfo-iterators=true | FileCheck %s
%class.A = type { i32, i32, i32, i32 }
define void @_Z3fooi(%class.A* sret(%class.A) %agg.result) #0 !dbg !3 {
diff --git a/llvm/test/Bitcode/dbg-record-roundtrip.ll b/llvm/test/Bitcode/dbg-record-roundtrip.ll
index 251c3d9f4bb7e0..bd347cac720677 100644
--- a/llvm/test/Bitcode/dbg-record-roundtrip.ll
+++ b/llvm/test/Bitcode/dbg-record-roundtrip.ll
@@ -10,6 +10,11 @@
; RUN: | llvm-dis --load-bitcode-into-experimental-debuginfo-iterators=true --write-experimental-debuginfo=true \
; RUN: | FileCheck %s --check-prefixes=RECORDS
+;; Load intrinsics directly into the new format (auto-upgrade).
+; RUN: llvm-as --write-experimental-debuginfo-iterators-to-bitcode=false %s -o - \
+; RUN: | llvm-dis --load-bitcode-into-experimental-debuginfo-iterators=true --write-experimental-debuginfo=true \
+; RUN: | FileCheck %s --check-prefixes=RECORDS
+
;; Check that verify-uselistorder passes regardless of input format.
; RUN: llvm-as %s --write-experimental-debuginfo-iterators-to-bitcode=true -o - | verify-uselistorder
; RUN: verify-uselistorder %s
diff --git a/llvm/test/Bitcode/upgrade-dbg-addr.ll b/llvm/test/Bitcode/upgrade-dbg-addr.ll
index 40fd7db18948b5..06a411c2c83486 100644
--- a/llvm/test/Bitcode/upgrade-dbg-addr.ll
+++ b/llvm/test/Bitcode/upgrade-dbg-addr.ll
@@ -1,6 +1,7 @@
; Test upgrade of dbg.addr intrinsics into dbg.value with DW_OP_deref appended
;
; RUN: llvm-dis < %s.bc | FileCheck %s
+; RUN: llvm-dis < %s.bc --load-bitcode-into-experimental-debuginfo-iterators --write-experimental-debuginfo=false | FileCheck %s
; RUN: verify-uselistorder < %s.bc
define i32 @example(i32 %num) {
More information about the llvm-commits
mailing list