[llvm] [DebugInfo][RemoveDIs] Use autoupgrader to convert old debug-info (PR #143452)
Jeremy Morse via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 11 02:34:30 PDT 2025
https://github.com/jmorse updated https://github.com/llvm/llvm-project/pull/143452
>From 852507298284866a69bd5a26be032b196d2d5e08 Mon Sep 17 00:00:00 2001
From: Jeremy Morse <jeremy.morse at sony.com>
Date: Tue, 3 Jun 2025 22:18:03 +0100
Subject: [PATCH 1/7] [DebugInfo][RemoveDIs] Use autoupgrader to convert old
debug-info
By chance, two things have prevented the autoupgrade path being exercised
much so far:
* LLParser setting the debug-info mode to "old" on seeing intrinsics,
* The test in AutoUpgrade.cpp wanting to upgrade into a "new" debug-info
block.
In practice, this appears to mean this code path hasn't seen the various
invalid inputs that can come its way. This commit does a number of things:
* Tolerates the various illegal inputs that can be written with
debug-intrinsics, and that must be tolerated until the Verifier runs,
* Printing illegal/null DbgRecord fields must succeed,
* Verifier errors need to localise the function/block where the error is,
* Tests that now see debug records will print debug-record errors,
Plus a few new tests for other intrinsic-to-debug-record failures modes I
found. There are also two edge cases:
* Some of the unit tests switch back and forth between intrinsic and
record modes at will; I've deleted coverage and some assertions to
tolerate this as intrinsic support is now Gone (TM),
* In sroa-extract-bits.ll, the order of debug records flips. This is
because the autoupgrader upgrades in the opposite order to the basic
block conversion routines... which doesn't change the record order, but
_does_ change the use list order in Metadata! This should (TM) have no
consequence to the correctness of LLVM, but will change the order of
various records and the order of DWARF record output too.
I tried to reduce this patch to a smaller collection of changes, but
they're all intertwined, sorry.
---
llvm/lib/AsmParser/LLParser.cpp | 2 -
llvm/lib/IR/AsmWriter.cpp | 36 ++++--
llvm/lib/IR/AutoUpgrade.cpp | 29 +++--
llvm/lib/IR/BasicBlock.cpp | 4 -
llvm/lib/IR/Verifier.cpp | 24 ++--
.../drop-debug-info-nonzero-alloca.ll | 6 +-
.../parse-and-verify/verify.ll | 18 +--
.../DebugInfo/Generic/sroa-extract-bits.ll | 28 ++---
.../IROutliner/outlining-debug-statements.ll | 3 +-
llvm/test/Transforms/ObjCARC/code-motion.ll | 13 +-
.../RemoveDI/invalid-dbg-declare-operands.ll | 80 +++++++++++++
.../Verifier/dbg-declare-invalid-debug-loc.ll | 113 ++++++++++++++++++
.../diexpression-entry-value-llvm-ir.ll | 6 +-
.../test/Verifier/llvm.dbg.declare-address.ll | 4 +-
.../Verifier/llvm.dbg.declare-expression.ll | 4 +-
.../Verifier/llvm.dbg.declare-variable.ll | 4 +-
.../llvm.dbg.intrinsic-dbg-attachment.ll | 16 +--
.../Verifier/llvm.dbg.value-expression.ll | 4 +-
llvm/test/Verifier/llvm.dbg.value-value.ll | 4 +-
llvm/test/Verifier/llvm.dbg.value-variable.ll | 4 +-
llvm/unittests/IR/DebugInfoTest.cpp | 13 --
21 files changed, 313 insertions(+), 102 deletions(-)
create mode 100644 llvm/test/Verifier/RemoveDI/invalid-dbg-declare-operands.ll
create mode 100644 llvm/test/Verifier/dbg-declare-invalid-debug-loc.ll
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index b933d240c4d27..5c007dcf00224 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -8336,8 +8336,6 @@ bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS,
return error(CallLoc, "llvm.dbg intrinsic should not appear in a module "
"using non-intrinsic debug info");
}
- if (!SeenOldDbgInfoFormat)
- M->setNewDbgInfoFormatFlag(false);
SeenOldDbgInfoFormat = true;
}
CI->setAttributes(PAL);
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 7223dd845d18d..598a8e141b1dd 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1204,6 +1204,10 @@ void SlotTracker::processFunctionMetadata(const Function &F) {
}
void SlotTracker::processDbgRecordMetadata(const DbgRecord &DR) {
+ // Tolerate null metadata pointers: it's a completely illegal debug record,
+ // but we can have faulty metadata from debug-intrinsic days being
+ // autoupgraded into debug records. This gets caught by the verifier, which
+ // then will print the faulty IR, hitting this code path.
if (const DbgVariableRecord *DVR = dyn_cast<const DbgVariableRecord>(&DR)) {
// Process metadata used by DbgRecords; we only specifically care about the
// DILocalVariable, DILocation, and DIAssignID fields, as the Value and
@@ -1211,9 +1215,11 @@ void SlotTracker::processDbgRecordMetadata(const DbgRecord &DR) {
// Note: The above doesn't apply for empty-metadata operands.
if (auto *Empty = dyn_cast<MDNode>(DVR->getRawLocation()))
CreateMetadataSlot(Empty);
- CreateMetadataSlot(DVR->getRawVariable());
+ if (DVR->getRawVariable())
+ CreateMetadataSlot(DVR->getRawVariable());
if (DVR->isDbgAssign()) {
- CreateMetadataSlot(cast<MDNode>(DVR->getRawAssignID()));
+ if (auto *AssignID = DVR->getRawAssignID())
+ CreateMetadataSlot(cast<MDNode>(AssignID));
if (auto *Empty = dyn_cast<MDNode>(DVR->getRawAddress()))
CreateMetadataSlot(Empty);
}
@@ -1222,7 +1228,8 @@ void SlotTracker::processDbgRecordMetadata(const DbgRecord &DR) {
} else {
llvm_unreachable("unsupported DbgRecord kind");
}
- CreateMetadataSlot(DR.getDebugLoc().getAsMDNode());
+ if (DR.getDebugLoc())
+ CreateMetadataSlot(DR.getDebugLoc().getAsMDNode());
}
void SlotTracker::processInstructionMetadata(const Instruction &I) {
@@ -4867,22 +4874,31 @@ void AssemblyWriter::printDbgVariableRecord(const DbgVariableRecord &DVR) {
llvm_unreachable(
"Tried to print a DbgVariableRecord with an invalid LocationType!");
}
+
+ auto PrintOrNull = [&](Metadata *M) {
+ if (!M) {
+ Out << "(null)";
+ } else {
+ WriteAsOperandInternal(Out, M, WriterCtx, true);
+ }
+ };
+
Out << "(";
- WriteAsOperandInternal(Out, DVR.getRawLocation(), WriterCtx, true);
+ PrintOrNull(DVR.getRawLocation());
Out << ", ";
- WriteAsOperandInternal(Out, DVR.getRawVariable(), WriterCtx, true);
+ PrintOrNull(DVR.getRawVariable());
Out << ", ";
- WriteAsOperandInternal(Out, DVR.getRawExpression(), WriterCtx, true);
+ PrintOrNull(DVR.getRawExpression());
Out << ", ";
if (DVR.isDbgAssign()) {
- WriteAsOperandInternal(Out, DVR.getRawAssignID(), WriterCtx, true);
+ PrintOrNull(DVR.getRawAssignID());
Out << ", ";
- WriteAsOperandInternal(Out, DVR.getRawAddress(), WriterCtx, true);
+ PrintOrNull(DVR.getRawAddress());
Out << ", ";
- WriteAsOperandInternal(Out, DVR.getRawAddressExpression(), WriterCtx, true);
+ PrintOrNull(DVR.getRawAddressExpression());
Out << ", ";
}
- WriteAsOperandInternal(Out, DVR.getDebugLoc().getAsMDNode(), WriterCtx, true);
+ PrintOrNull(DVR.getDebugLoc().getAsMDNode());
Out << ")";
}
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 814c00c669cb3..58875e59c727d 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -1155,8 +1155,7 @@ static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn,
case 'd':
if (Name.consume_front("dbg.")) {
// Mark debug intrinsics for upgrade to new debug format.
- if (CanUpgradeDebugIntrinsicsToRecords &&
- F->getParent()->IsNewDbgInfoFormat) {
+ if (CanUpgradeDebugIntrinsicsToRecords) {
if (Name == "addr" || Name == "value" || Name == "assign" ||
Name == "declare" || Name == "label") {
// There's no function to replace these with.
@@ -4398,11 +4397,25 @@ static Value *upgradeAMDGCNIntrinsicCall(StringRef Name, CallBase *CI,
/// 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());
+ if (Op < CI->arg_size()) {
+ if (MetadataAsValue *MAV = dyn_cast<MetadataAsValue>(CI->getArgOperand(Op)))
+ // Use a reinterpret cast rather than a safe default-to-null cast: the
+ // autoupgrade process happens before the verifier, and thus there might
+ // be some nonsense metadata in there.
+ return reinterpret_cast<MDType*>(MAV->getMetadata());
+ }
return nullptr;
}
+static const DILocation *getDebugLocSafe(const Instruction *I) {
+ MDNode *MD = I->getDebugLoc().getAsMDNode();
+ // Use a C-style cast here rather than cast<DILocation>. The autoupgrader
+ // runs before the verifier, so the Metadata could refer to anything. Allow
+ // the verifier to detect and produce an error message, which will be much
+ // more ergonomic to the user.
+ return (const DILocation*)MD;
+}
+
/// 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.
@@ -4415,11 +4428,11 @@ static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) {
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());
+ getDebugLocSafe(CI));
} else if (Name == "declare") {
DR = new DbgVariableRecord(
unwrapMAVOp<Metadata>(CI, 0), unwrapMAVOp<DILocalVariable>(CI, 1),
- unwrapMAVOp<DIExpression>(CI, 2), CI->getDebugLoc(),
+ unwrapMAVOp<DIExpression>(CI, 2), getDebugLocSafe(CI),
DbgVariableRecord::LocationType::Declare);
} else if (Name == "addr") {
// Upgrade dbg.addr to dbg.value with DW_OP_deref.
@@ -4427,7 +4440,7 @@ static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) {
Expr = DIExpression::append(Expr, dwarf::DW_OP_deref);
DR = new DbgVariableRecord(unwrapMAVOp<Metadata>(CI, 0),
unwrapMAVOp<DILocalVariable>(CI, 1), Expr,
- CI->getDebugLoc());
+ getDebugLocSafe(CI));
} else if (Name == "value") {
// An old version of dbg.value had an extra offset argument.
unsigned VarOp = 1;
@@ -4442,7 +4455,7 @@ static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) {
}
DR = new DbgVariableRecord(
unwrapMAVOp<Metadata>(CI, 0), unwrapMAVOp<DILocalVariable>(CI, VarOp),
- unwrapMAVOp<DIExpression>(CI, ExprOp), CI->getDebugLoc());
+ unwrapMAVOp<DIExpression>(CI, ExprOp), getDebugLocSafe(CI));
}
assert(DR && "Unhandled intrinsic kind in upgrade to DbgRecord");
CI->getParent()->insertDbgRecordBefore(DR, CI->getIterator());
diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp
index ed11ea06398f1..f716e9970b841 100644
--- a/llvm/lib/IR/BasicBlock.cpp
+++ b/llvm/lib/IR/BasicBlock.cpp
@@ -32,8 +32,6 @@ using namespace llvm;
STATISTIC(NumInstrRenumberings, "Number of renumberings across all blocks");
DbgMarker *BasicBlock::createMarker(Instruction *I) {
- assert(IsNewDbgInfoFormat &&
- "Tried to create a marker in a non new debug-info block!");
if (I->DebugMarker)
return I->DebugMarker;
DbgMarker *Marker = new DbgMarker();
@@ -43,8 +41,6 @@ DbgMarker *BasicBlock::createMarker(Instruction *I) {
}
DbgMarker *BasicBlock::createMarker(InstListType::iterator It) {
- assert(IsNewDbgInfoFormat &&
- "Tried to create a marker in a non new debug-info block!");
if (It != end())
return createMarker(&*It);
DbgMarker *DM = getTrailingDbgRecords();
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 2d03a7a261b5b..17e76902fc0b5 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -6710,7 +6710,7 @@ void Verifier::visit(DbgVariableRecord &DVR) {
CheckDI(DVR.getType() == DbgVariableRecord::LocationType::Value ||
DVR.getType() == DbgVariableRecord::LocationType::Declare ||
DVR.getType() == DbgVariableRecord::LocationType::Assign,
- "invalid #dbg record type", &DVR, DVR.getType());
+ "invalid #dbg record type", &DVR, DVR.getType(), BB, F);
// The location for a DbgVariableRecord must be either a ValueAsMetadata,
// DIArgList, or an empty MDNode (which is a legacy representation for an
@@ -6718,30 +6718,30 @@ void Verifier::visit(DbgVariableRecord &DVR) {
auto *MD = DVR.getRawLocation();
CheckDI(MD && (isa<ValueAsMetadata>(MD) || isa<DIArgList>(MD) ||
(isa<MDNode>(MD) && !cast<MDNode>(MD)->getNumOperands())),
- "invalid #dbg record address/value", &DVR, MD);
+ "invalid #dbg record address/value", &DVR, MD, BB, F);
if (auto *VAM = dyn_cast<ValueAsMetadata>(MD)) {
visitValueAsMetadata(*VAM, F);
if (DVR.isDbgDeclare()) {
// Allow integers here to support inttoptr salvage.
Type *Ty = VAM->getValue()->getType();
CheckDI(Ty->isPointerTy() || Ty->isIntegerTy(),
- "location of #dbg_declare must be a pointer or int", &DVR, MD);
+ "location of #dbg_declare must be a pointer or int", &DVR, MD, BB, F);
}
} else if (auto *AL = dyn_cast<DIArgList>(MD)) {
visitDIArgList(*AL, F);
}
CheckDI(isa_and_nonnull<DILocalVariable>(DVR.getRawVariable()),
- "invalid #dbg record variable", &DVR, DVR.getRawVariable());
+ "invalid #dbg record variable", &DVR, DVR.getRawVariable(), BB, F);
visitMDNode(*DVR.getRawVariable(), AreDebugLocsAllowed::No);
CheckDI(isa_and_nonnull<DIExpression>(DVR.getRawExpression()),
- "invalid #dbg record expression", &DVR, DVR.getRawExpression());
+ "invalid #dbg record expression", &DVR, DVR.getRawExpression(), BB, F);
visitMDNode(*DVR.getExpression(), AreDebugLocsAllowed::No);
if (DVR.isDbgAssign()) {
CheckDI(isa_and_nonnull<DIAssignID>(DVR.getRawAssignID()),
- "invalid #dbg_assign DIAssignID", &DVR, DVR.getRawAssignID());
+ "invalid #dbg_assign DIAssignID", &DVR, DVR.getRawAssignID(), BB, F);
visitMDNode(*cast<DIAssignID>(DVR.getRawAssignID()),
AreDebugLocsAllowed::No);
@@ -6752,29 +6752,29 @@ void Verifier::visit(DbgVariableRecord &DVR) {
CheckDI(
isa<ValueAsMetadata>(RawAddr) ||
(isa<MDNode>(RawAddr) && !cast<MDNode>(RawAddr)->getNumOperands()),
- "invalid #dbg_assign address", &DVR, DVR.getRawAddress());
+ "invalid #dbg_assign address", &DVR, DVR.getRawAddress(), BB, F);
if (auto *VAM = dyn_cast<ValueAsMetadata>(RawAddr))
visitValueAsMetadata(*VAM, F);
CheckDI(isa_and_nonnull<DIExpression>(DVR.getRawAddressExpression()),
"invalid #dbg_assign address expression", &DVR,
- DVR.getRawAddressExpression());
+ DVR.getRawAddressExpression(), BB, F);
visitMDNode(*DVR.getAddressExpression(), AreDebugLocsAllowed::No);
// All of the linked instructions should be in the same function as DVR.
for (Instruction *I : at::getAssignmentInsts(&DVR))
CheckDI(DVR.getFunction() == I->getFunction(),
- "inst not in same function as #dbg_assign", I, &DVR);
+ "inst not in same function as #dbg_assign", I, &DVR, BB, F);
}
// This check is redundant with one in visitLocalVariable().
DILocalVariable *Var = DVR.getVariable();
CheckDI(isType(Var->getRawType()), "invalid type ref", Var,
- Var->getRawType());
+ Var->getRawType(), BB, F);
auto *DLNode = DVR.getDebugLoc().getAsMDNode();
CheckDI(isa_and_nonnull<DILocation>(DLNode), "invalid #dbg record DILocation",
- &DVR, DLNode);
+ &DVR, DLNode, BB, F);
DILocation *Loc = DVR.getDebugLoc();
// The scopes for variables and !dbg attachments must agree.
@@ -6786,7 +6786,7 @@ void Verifier::visit(DbgVariableRecord &DVR) {
CheckDI(VarSP == LocSP,
"mismatched subprogram between #dbg record variable and DILocation",
&DVR, BB, F, Var, Var->getScope()->getSubprogram(), Loc,
- Loc->getScope()->getSubprogram());
+ Loc->getScope()->getSubprogram(), BB, F);
verifyFnArgs(DVR);
}
diff --git a/llvm/test/Assembler/drop-debug-info-nonzero-alloca.ll b/llvm/test/Assembler/drop-debug-info-nonzero-alloca.ll
index 2b089d2639375..c8b235757afba 100644
--- a/llvm/test/Assembler/drop-debug-info-nonzero-alloca.ll
+++ b/llvm/test/Assembler/drop-debug-info-nonzero-alloca.ll
@@ -12,8 +12,12 @@ entry:
metadata ptr undef,
metadata !DILocalVariable(scope: !1),
metadata !DIExpression())
-; AS: llvm.dbg.value intrinsic requires a !dbg attachment
+; AS: invalid #dbg record DILocation
+; AS: #dbg_value(ptr undef, !{{[0-9]+}}, !DIExpression(), (null))
+; AS: label %entry
+; AS: ptr @foo
; AS: warning: ignoring invalid debug info in <stdin>
+
ret void
}
diff --git a/llvm/test/DebugInfo/Generic/assignment-tracking/parse-and-verify/verify.ll b/llvm/test/DebugInfo/Generic/assignment-tracking/parse-and-verify/verify.ll
index 0a4b7c255dc71..d1f1e1ce768dc 100644
--- a/llvm/test/DebugInfo/Generic/assignment-tracking/parse-and-verify/verify.ll
+++ b/llvm/test/DebugInfo/Generic/assignment-tracking/parse-and-verify/verify.ll
@@ -8,7 +8,7 @@
define dso_local void @fun2() !dbg !15 {
;; DIAssignID copied here from @fun() where it is used by intrinsics.
- ; CHECK: dbg.assign not in same function as inst
+ ; CHECK: DVRAssign not in same function as inst
%x = alloca i32, align 4, !DIAssignID !14
ret void
}
@@ -17,24 +17,24 @@ define dso_local void @fun() !dbg !7 {
entry:
%a = alloca i32, align 4, !DIAssignID !14
;; Here something other than a dbg.assign intrinsic is using a DIAssignID.
- ; CHECK: !DIAssignID should only be used by llvm.dbg.assign intrinsics
+ ; CHECK: !DIAssignID should only be used by Assign DVRs
call void @llvm.dbg.value(metadata !14, metadata !10, metadata !DIExpression()), !dbg !13
;; Each following dbg.assign has an argument of the incorrect type.
- ; CHECK: invalid llvm.dbg.assign intrinsic address/value
+ ; CHECK: invalid #dbg record address/value
call void @llvm.dbg.assign(metadata !3, metadata !10, metadata !DIExpression(), metadata !14, metadata ptr undef, metadata !DIExpression()), !dbg !13
- ; CHECK: invalid llvm.dbg.assign intrinsic variable
+ ; CHECK: invalid #dbg record variable
call void @llvm.dbg.assign(metadata i32 0, metadata !2, metadata !DIExpression(), metadata !14, metadata ptr undef, metadata !DIExpression()), !dbg !13
- ; CHECK: invalid llvm.dbg.assign intrinsic expression
+ ; CHECK: invalid #dbg record expression
call void @llvm.dbg.assign(metadata !14, metadata !10, metadata !2, metadata !14, metadata ptr undef, metadata !DIExpression()), !dbg !13
- ; CHECK: invalid llvm.dbg.assign intrinsic DIAssignID
+ ; CHECK: invalid #dbg_assign DIAssignID
call void @llvm.dbg.assign(metadata !14, metadata !10, metadata !DIExpression(), metadata !2, metadata ptr undef, metadata !DIExpression()), !dbg !13
- ; CHECK: invalid llvm.dbg.assign intrinsic address
+ ; CHECK: invalid #dbg_assign address
call void @llvm.dbg.assign(metadata !14, metadata !10, metadata !DIExpression(), metadata !14, metadata !3, metadata !DIExpression()), !dbg !13
;; Empty metadata debug operands are allowed.
- ; CHECK-NOT: invalid llvm.dbg.assign
+ ; CHECK-NOT: invalid #dbg record
call void @llvm.dbg.assign(metadata !14, metadata !10, metadata !DIExpression(), metadata !14, metadata !2, metadata !DIExpression()), !dbg !13
- ; CHECK: invalid llvm.dbg.assign intrinsic address expression
+ ; CHECK: invalid #dbg_assign address expression
call void @llvm.dbg.assign(metadata !14, metadata !10, metadata !DIExpression(), metadata !14, metadata ptr undef, metadata !2), !dbg !13
ret void
}
diff --git a/llvm/test/DebugInfo/Generic/sroa-extract-bits.ll b/llvm/test/DebugInfo/Generic/sroa-extract-bits.ll
index f47e495db6617..6db453605cb57 100644
--- a/llvm/test/DebugInfo/Generic/sroa-extract-bits.ll
+++ b/llvm/test/DebugInfo/Generic/sroa-extract-bits.ll
@@ -13,8 +13,8 @@ define i8 @test1(i32 %arg) {
; CHECK-NEXT: #dbg_value(i8 [[PTR_SROA_0_0_EXTRACT_TRUNC]], [[META2:![0-9]+]], !DIExpression(DW_OP_LLVM_extract_bits_zext, 0, 8), [[META7:![0-9]+]])
; CHECK-NEXT: [[PTR_SROA_2_0_EXTRACT_SHIFT:%.*]] = lshr i32 [[ARG]], 8
; CHECK-NEXT: [[PTR_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[PTR_SROA_2_0_EXTRACT_SHIFT]] to i24
-; CHECK-NEXT: #dbg_value(i24 [[PTR_SROA_2_0_EXTRACT_TRUNC]], [[META8:![0-9]+]], !DIExpression(DW_OP_LLVM_extract_bits_zext, 8, 16), [[META7]])
-; CHECK-NEXT: #dbg_value(i24 [[PTR_SROA_2_0_EXTRACT_TRUNC]], [[META9:![0-9]+]], !DIExpression(DW_OP_LLVM_extract_bits_sext, 0, 8), [[META7]])
+; CHECK-NEXT: #dbg_value(i24 [[PTR_SROA_2_0_EXTRACT_TRUNC]], [[META8:![0-9]+]], !DIExpression(DW_OP_LLVM_extract_bits_sext, 0, 8), [[META7]])
+; CHECK-NEXT: #dbg_value(i24 [[PTR_SROA_2_0_EXTRACT_TRUNC]], [[META10:![0-9]+]], !DIExpression(DW_OP_LLVM_extract_bits_zext, 8, 16), [[META7]])
; CHECK-NEXT: ret i8 [[PTR_SROA_0_0_EXTRACT_TRUNC]]
;
entry:
@@ -36,11 +36,11 @@ define i8 @test2(i32 %arg1, i8 %arg2) {
; CHECK-NEXT: #dbg_value(i8 [[PTR_SROA_0_0_EXTRACT_TRUNC]], [[META2]], !DIExpression(DW_OP_LLVM_extract_bits_zext, 0, 8), [[META7]])
; CHECK-NEXT: [[PTR_SROA_2_0_EXTRACT_SHIFT:%.*]] = lshr i32 [[ARG1]], 8
; CHECK-NEXT: [[PTR_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[PTR_SROA_2_0_EXTRACT_SHIFT]] to i16
-; CHECK-NEXT: #dbg_value(i16 [[PTR_SROA_2_0_EXTRACT_TRUNC]], [[META9]], !DIExpression(DW_OP_LLVM_extract_bits_sext, 0, 16), [[META7]])
+; CHECK-NEXT: #dbg_value(i16 [[PTR_SROA_2_0_EXTRACT_TRUNC]], [[META8]], !DIExpression(DW_OP_LLVM_extract_bits_sext, 0, 16), [[META7]])
; CHECK-NEXT: [[PTR_SROA_21_0_EXTRACT_SHIFT:%.*]] = lshr i32 [[ARG1]], 24
; CHECK-NEXT: [[PTR_SROA_21_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[PTR_SROA_21_0_EXTRACT_SHIFT]] to i8
-; CHECK-NEXT: #dbg_value(i8 [[PTR_SROA_21_0_EXTRACT_TRUNC]], [[META8]], !DIExpression(DW_OP_LLVM_extract_bits_zext, 0, 8), [[META7]])
-; CHECK-NEXT: #dbg_value(i8 [[ARG2]], [[META8]], !DIExpression(DW_OP_LLVM_extract_bits_zext, 0, 8), [[META7]])
+; CHECK-NEXT: #dbg_value(i8 [[PTR_SROA_21_0_EXTRACT_TRUNC]], [[META10]], !DIExpression(DW_OP_LLVM_extract_bits_zext, 0, 8), [[META7]])
+; CHECK-NEXT: #dbg_value(i8 [[ARG2]], [[META10]], !DIExpression(DW_OP_LLVM_extract_bits_zext, 0, 8), [[META7]])
; CHECK-NEXT: ret i8 [[PTR_SROA_0_0_EXTRACT_TRUNC]]
;
entry:
@@ -84,7 +84,7 @@ define i16 @test4(i32 %arg) {
; CHECK-NEXT: #dbg_value(i16 [[PTR_SROA_0_0_EXTRACT_TRUNC]], [[META2]], !DIExpression(DW_OP_LLVM_extract_bits_zext, 0, 8), [[META7]])
; CHECK-NEXT: [[PTR_SROA_2_0_EXTRACT_SHIFT:%.*]] = lshr i32 [[ARG]], 16
; CHECK-NEXT: [[PTR_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[PTR_SROA_2_0_EXTRACT_SHIFT]] to i16
-; CHECK-NEXT: #dbg_value(i16 [[PTR_SROA_2_0_EXTRACT_TRUNC]], [[META8]], !DIExpression(DW_OP_LLVM_extract_bits_zext, 8, 8), [[META7]])
+; CHECK-NEXT: #dbg_value(i16 [[PTR_SROA_2_0_EXTRACT_TRUNC]], [[META10]], !DIExpression(DW_OP_LLVM_extract_bits_zext, 8, 8), [[META7]])
; CHECK-NEXT: ret i16 [[PTR_SROA_0_0_EXTRACT_TRUNC]]
;
entry:
@@ -107,8 +107,8 @@ define i8 @test5(i32 %arg) {
; CHECK-NEXT: #dbg_value(i8 [[PTR_SROA_0_0_EXTRACT_TRUNC]], [[META11:![0-9]+]], !DIExpression(), [[META7]])
; CHECK-NEXT: [[PTR_SROA_2_0_EXTRACT_SHIFT:%.*]] = lshr i32 [[ARG]], 8
; CHECK-NEXT: [[PTR_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[PTR_SROA_2_0_EXTRACT_SHIFT]] to i24
-; CHECK-NEXT: #dbg_value(i24 [[PTR_SROA_2_0_EXTRACT_TRUNC]], [[META8]], !DIExpression(DW_OP_LLVM_extract_bits_zext, 8, 8), [[META7]])
-; CHECK-NEXT: #dbg_value(i24 [[PTR_SROA_2_0_EXTRACT_TRUNC]], [[META9]], !DIExpression(DW_OP_LLVM_extract_bits_sext, 0, 8), [[META7]])
+; CHECK-NEXT: #dbg_value(i24 [[PTR_SROA_2_0_EXTRACT_TRUNC]], [[META8]], !DIExpression(DW_OP_LLVM_extract_bits_sext, 0, 8), [[META7]])
+; CHECK-NEXT: #dbg_value(i24 [[PTR_SROA_2_0_EXTRACT_TRUNC]], [[META10]], !DIExpression(DW_OP_LLVM_extract_bits_zext, 8, 8), [[META7]])
; CHECK-NEXT: ret i8 [[PTR_SROA_0_0_EXTRACT_TRUNC]]
;
entry:
@@ -130,11 +130,11 @@ define i8 @test6(i32 %arg1, i8 %arg2) {
; CHECK-NEXT: #dbg_value(i8 poison, [[META2]], !DIExpression(DW_OP_LLVM_extract_bits_sext, 0, 8), [[META7]])
; CHECK-NEXT: [[PTR_SROA_2_0_EXTRACT_SHIFT:%.*]] = lshr i32 [[ARG1]], 8
; CHECK-NEXT: [[PTR_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[PTR_SROA_2_0_EXTRACT_SHIFT]] to i16
-; CHECK-NEXT: #dbg_value(i16 poison, [[META9]], !DIExpression(DW_OP_LLVM_extract_bits_zext, 0, 16), [[META7]])
+; CHECK-NEXT: #dbg_value(i16 poison, [[META8]], !DIExpression(DW_OP_LLVM_extract_bits_zext, 0, 16), [[META7]])
; CHECK-NEXT: [[PTR_SROA_21_0_EXTRACT_SHIFT:%.*]] = lshr i32 [[ARG1]], 24
; CHECK-NEXT: [[PTR_SROA_21_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[PTR_SROA_21_0_EXTRACT_SHIFT]] to i8
-; CHECK-NEXT: #dbg_value(i8 poison, [[META8]], !DIExpression(DW_OP_LLVM_extract_bits_sext, 0, 8), [[META7]])
-; CHECK-NEXT: #dbg_value(i8 poison, [[META8]], !DIExpression(DW_OP_LLVM_extract_bits_sext, 0, 8), [[META7]])
+; CHECK-NEXT: #dbg_value(i8 poison, [[META10]], !DIExpression(DW_OP_LLVM_extract_bits_sext, 0, 8), [[META7]])
+; CHECK-NEXT: #dbg_value(i8 poison, [[META10]], !DIExpression(DW_OP_LLVM_extract_bits_sext, 0, 8), [[META7]])
; CHECK-NEXT: ret i8 [[PTR_SROA_0_0_EXTRACT_TRUNC]]
;
entry:
@@ -197,9 +197,9 @@ entry:
; CHECK: [[META5]] = !DIFile(filename: "dbg-bit-piece.cpp", directory: "")
; CHECK: [[META6]] = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned)
; CHECK: [[META7]] = !DILocation(line: 0, scope: [[META3]])
-; CHECK: [[META8]] = !DILocalVariable(name: "z", scope: [[META3]], type: [[META6]])
-; CHECK: [[META9]] = !DILocalVariable(name: "y", scope: [[META3]], type: [[META10:![0-9]+]])
-; CHECK: [[META10]] = !DIBasicType(name: "signed int", size: 32, encoding: DW_ATE_signed)
+; CHECK: [[META8]] = !DILocalVariable(name: "y", scope: [[META3]], type: [[META9:![0-9]+]])
+; CHECK: [[META9]] = !DIBasicType(name: "signed int", size: 32, encoding: DW_ATE_signed)
+; CHECK: [[META10]] = !DILocalVariable(name: "z", scope: [[META3]], type: [[META6]])
; CHECK: [[META11]] = !DILocalVariable(name: "x", scope: [[META3]], type: [[META12:![0-9]+]])
; CHECK: [[META12]] = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
;.
diff --git a/llvm/test/Transforms/IROutliner/outlining-debug-statements.ll b/llvm/test/Transforms/IROutliner/outlining-debug-statements.ll
index bf846c310a525..c1140988fa916 100644
--- a/llvm/test/Transforms/IROutliner/outlining-debug-statements.ll
+++ b/llvm/test/Transforms/IROutliner/outlining-debug-statements.ll
@@ -19,7 +19,7 @@ entry:
%c = alloca i32, align 4
store i32 2, ptr %a, align 4
store i32 3, ptr %b, align 4
- call void @llvm.dbg.value(metadata i64 0, metadata !14, metadata !DIExpression()), !dbg !14
+ call void @llvm.dbg.value(metadata i64 0, metadata !14, metadata !DIExpression()), !dbg !15
store i32 4, ptr %c, align 4
%al = load i32, ptr %a
%bl = load i32, ptr %b
@@ -62,3 +62,4 @@ entry:
!12 = !DISubroutineType(types: !13)
!13 = !{}
!14 = !DILocalVariable(name: "p_6", arg: 1, scope: !11, line: 117, type: !1)
+!15 = !DILocation(line: 1, scope: !11)
diff --git a/llvm/test/Transforms/ObjCARC/code-motion.ll b/llvm/test/Transforms/ObjCARC/code-motion.ll
index 499ee77bc6541..9009b98b4b1e3 100644
--- a/llvm/test/Transforms/ObjCARC/code-motion.ll
+++ b/llvm/test/Transforms/ObjCARC/code-motion.ll
@@ -1,4 +1,4 @@
-; RUN: opt -passes=objc-arc -S < %s | FileCheck %s
+; RUN: opt -passes=objc-arc -S < %s 2>&1 | FileCheck %s '--implicit-check-not=ignoring invalid debug'
declare void @alterRefCount()
declare void @use(ptr)
@@ -17,7 +17,7 @@ define i32 @test(ptr %x, ptr %y, i8 %z, i32 %i) {
store i32 %i, ptr %i.addr, align 4
%v1 = tail call ptr @llvm.objc.retain(ptr %x)
store i8 %z, ptr %x
- call void @llvm.dbg.declare(metadata ptr %i.addr, metadata !9, metadata !DIExpression()), !dbg !10
+ call void @llvm.dbg.declare(metadata ptr %i.addr, metadata !11, metadata !DIExpression()), !dbg !10
call void @alterRefCount()
tail call void @llvm.objc.release(ptr %x)
ret i32 %i
@@ -64,7 +64,7 @@ define void @test3(ptr %obj, i1 %cond) {
; CHECK-NEXT: call void @use(ptr [[OBJ]])
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
-; CHECK-NEXT: call void @llvm.objc.release(ptr [[OBJ]]) {{.*}}, !clang.imprecise_release !2
+; CHECK-NEXT: call void @llvm.objc.release(ptr [[OBJ]]) {{.*}}, !clang.imprecise_release ![[EMPTYMETA:[0-9]+]]
; CHECK-NEXT: ret void
;
%v0 = call ptr @llvm.objc.retain(ptr %obj)
@@ -102,8 +102,8 @@ define void @test4(ptr %obj0, ptr %obj1, i1 %cond) {
; CHECK-NEXT: call void @use(ptr [[OBJ1]])
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
-; CHECK-NEXT: call void @llvm.objc.release(ptr [[OBJ0]]) {{.*}}, !clang.imprecise_release !2
-; CHECK-NEXT: call void @llvm.objc.release(ptr [[OBJ1]]) {{.*}}, !clang.imprecise_release !2
+; CHECK-NEXT: call void @llvm.objc.release(ptr [[OBJ0]]) {{.*}}, !clang.imprecise_release ![[EMPTYMETA]]
+; CHECK-NEXT: call void @llvm.objc.release(ptr [[OBJ1]]) {{.*}}, !clang.imprecise_release ![[EMPTYMETA]]
; CHECK-NEXT: ret void
;
%v0 = call ptr @llvm.objc.retain(ptr %obj0)
@@ -190,6 +190,8 @@ attributes #0 = { readonly }
!llvm.module.flags = !{!0, !1}
+; CHECK: ![[EMPTYMETA]] = !{}
+
!0 = !{i32 2, !"Dwarf Version", i32 4}
!1 = !{i32 2, !"Debug Info Version", i32 3}
!2 = !DILocalVariable(name: "i", arg: 1, scope: !3, file: !4, line: 1, type: !7)
@@ -201,3 +203,4 @@ attributes #0 = { readonly }
!8 = distinct !DICompileUnit(language: DW_LANG_ObjC, file: !4, isOptimized: false, runtimeVersion: 2, emissionKind: FullDebug, enums: !9, nameTableKind: None)
!9 = !{}
!10 = !DILocation(line: 1, column: 14, scope: !3)
+!11 = !DILocalVariable(name: "foo", scope: !3, type: !7)
diff --git a/llvm/test/Verifier/RemoveDI/invalid-dbg-declare-operands.ll b/llvm/test/Verifier/RemoveDI/invalid-dbg-declare-operands.ll
new file mode 100644
index 0000000000000..71a287f3293cc
--- /dev/null
+++ b/llvm/test/Verifier/RemoveDI/invalid-dbg-declare-operands.ll
@@ -0,0 +1,80 @@
+; RUN: llvm-as %s -o - 2>&1 | FileCheck %s
+; CHECK: invalid #dbg record expression
+;
+; Fossilised debug-info with only two arguments to dbg.declare have been
+; spotted in LLVMs test suite (debug-info-always-inline.ll), test that this
+; does not cause a crash. LLVM needs to be able to autoupgrade invalid
+; dbg.declares to invalid #dbg_declares because this occurs before the
+; Verifier runs.
+
+; ModuleID = 'out.ll'
+source_filename = "llvm/test/DebugInfo/Generic/debug-info-always-inline.ll"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @llvm.dbg.declare(metadata, metadata, metadata)
+
+; Function Attrs: alwaysinline nounwind sspstrong
+define i32 @_Z3foov() #0 !dbg !7 {
+entry:
+ %arr = alloca [10 x i32], align 16, !dbg !10
+ %sum = alloca i32, align 4, !dbg !11
+ call void @llvm.dbg.declare(metadata ptr %sum, metadata !26), !dbg !11
+ store i32 5, ptr %arr, align 4, !dbg !12
+ store i32 4, ptr %sum, align 4, !dbg !13
+ %0 = load i32, ptr %sum, align 4, !dbg !14
+ ret i32 %0, !dbg !15
+}
+
+; Function Attrs: nounwind sspstrong
+define i32 @main() #1 !dbg !16 {
+entry:
+ %retval = alloca i32, align 4, !dbg !17
+ %i = alloca i32, align 4, !dbg !18
+ store i32 0, ptr %retval, align 4, !dbg !19
+ call void @_Z3barv(), !dbg !20
+ %call = call i32 @_Z3foov(), !dbg !21
+ store i32 %call, ptr %i, align 4, !dbg !22
+ %0 = load i32, ptr %i, align 4, !dbg !23
+ ret i32 %0, !dbg !24
+}
+
+declare void @_Z3barv() #2
+
+attributes #0 = { alwaysinline nounwind sspstrong "frame-pointer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind sspstrong "frame-pointer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { "frame-pointer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!llvm.dbg.cu = !{!3}
+!llvm.debugify = !{!5, !6}
+
+!0 = !{i32 2, !"Dwarf Version", i32 4}
+!1 = !{i32 2, !"Debug Info Version", i32 3}
+!2 = !{!"clang version 3.6.0 (217844)"}
+!3 = distinct !DICompileUnit(language: DW_LANG_C, file: !4, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
+!4 = !DIFile(filename: "/fast/fs/llvm-main/llvm/test/DebugInfo/Generic/debug-info-always-inline.ll", directory: "/")
+!5 = !{i32 14}
+!6 = !{i32 7}
+!7 = distinct !DISubprogram(name: "_Z3foov", linkageName: "_Z3foov", scope: null, file: !4, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !3, retainedNodes: !9)
+!8 = !DISubroutineType(types: !9)
+!9 = !{}
+!10 = !DILocation(line: 1, column: 1, scope: !7)
+!11 = !DILocation(line: 2, column: 1, scope: !7)
+!12 = !DILocation(line: 3, column: 1, scope: !7)
+!13 = !DILocation(line: 4, column: 1, scope: !7)
+!14 = !DILocation(line: 5, column: 1, scope: !7)
+!15 = !DILocation(line: 6, column: 1, scope: !7)
+!16 = distinct !DISubprogram(name: "main", linkageName: "main", scope: null, file: !4, line: 7, type: !8, scopeLine: 7, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !3, retainedNodes: !9)
+!17 = !DILocation(line: 7, column: 1, scope: !16)
+!18 = !DILocation(line: 8, column: 1, scope: !16)
+!19 = !DILocation(line: 9, column: 1, scope: !16)
+!20 = !DILocation(line: 10, column: 1, scope: !16)
+!21 = !DILocation(line: 11, column: 1, scope: !16)
+!22 = !DILocation(line: 12, column: 1, scope: !16)
+!23 = !DILocation(line: 13, column: 1, scope: !16)
+!24 = !DILocation(line: 14, column: 1, scope: !16)
+!25 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!26 = !DILocalVariable(name: "b", scope: !7, file: !4, line: 1234, type: !25)
+
diff --git a/llvm/test/Verifier/dbg-declare-invalid-debug-loc.ll b/llvm/test/Verifier/dbg-declare-invalid-debug-loc.ll
new file mode 100644
index 0000000000000..56f91b2b6b212
--- /dev/null
+++ b/llvm/test/Verifier/dbg-declare-invalid-debug-loc.ll
@@ -0,0 +1,113 @@
+; RUN: opt %s -o /dev/null -S 2>&1 | FileCheck %s
+;
+; The last dbg.declare intrinsic in this file has an illegal DILocation -- this
+; needs to pass through the autoupgrade to #dbg_declare process and then get
+; caught by the verifier.
+;
+; CHECK: invalid #dbg record DILocation
+; CHECK-NEXT: #dbg_declare(ptr %1, !61, !DIExpression(), !62)
+; CHECK-NEXT: !DISubprogram(name: "IgnoreIntrinsicTest",
+; CHECK-NEXT: label %0
+; CHECK-NEXT: ptr @IgnoreIntrinsicTest
+
+ at a = external global { i64, [56 x i8] }, align 32
+
+; Function Attrs: nounwind sspreq
+define i32 @_Z18read_response_sizev() #0 !dbg !9 {
+entry:
+ tail call void @llvm.dbg.value(metadata !22, i64 0, metadata !23, metadata !DIExpression()), !dbg !39
+ %0 = load i64, ptr @a, align 8, !dbg !40
+ tail call void @llvm.dbg.value(metadata i32 undef, i64 0, metadata !64, metadata !DIExpression()), !dbg !71
+ %1 = trunc i64 %0 to i32
+ ret i32 %1
+}
+
+define i32 @IgnoreIntrinsicTest() #1 {
+ %1 = alloca i32, align 4
+ call void @llvm.dbg.declare(metadata ptr %1, metadata !73, metadata !DIExpression()), !dbg !74
+ store volatile i32 1, ptr %1, align 4
+ %2 = load volatile i32, ptr %1, align 4
+ %3 = mul nsw i32 %2, 42
+ ret i32 %3
+}
+
+; Function Attrs: nounwind readnone
+declare void @llvm.dbg.value(metadata, i64, metadata, metadata)
+declare void @llvm.dbg.declare(metadata, metadata, metadata)
+
+attributes #0 = { sspreq }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!21, !72}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.4 ", isOptimized: true, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !5, globals: !20, imports: !5)
+!1 = !DIFile(filename: "<unknown>", directory: "/Users/matt/ryan_bug")
+!2 = !{!3}
+!3 = !DICompositeType(tag: DW_TAG_enumeration_type, line: 20, size: 32, align: 32, file: !1, scope: !4, elements: !6)
+!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "C", line: 19, size: 8, align: 8, file: !1, elements: !5)
+!5 = !{}
+!6 = !{!7}
+!7 = !DIEnumerator(name: "max_frame_size", value: 0) ; [ DW_TAG_enumerator ] [max_frame_size :: 0]
+!9 = distinct !DISubprogram(name: "read_response_size", linkageName: "_Z18read_response_sizev", line: 27, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 27, file: !1, scope: !10, type: !11, retainedNodes: !14)
+!10 = !DIFile(filename: "<unknown>", directory: "/Users/matt/ryan_bug")
+!11 = !DISubroutineType(types: !12)
+!12 = !{!13}
+!13 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
+!14 = !{!15, !19}
+!15 = !DILocalVariable(name: "b", line: 28, scope: !9, file: !10, type: !16)
+!16 = !DICompositeType(tag: DW_TAG_structure_type, name: "B", line: 16, size: 32, align: 32, file: !1, elements: !17)
+!17 = !{!18}
+!18 = !DIDerivedType(tag: DW_TAG_member, name: "end_of_file", line: 17, size: 32, align: 32, file: !1, scope: !16, baseType: !13)
+!19 = !DILocalVariable(name: "c", line: 29, scope: !9, file: !10, type: !13)
+!20 = !{}
+!21 = !{i32 2, !"Dwarf Version", i32 2}
+!22 = !{ptr @a}
+!23 = !DILocalVariable(name: "p2", line: 12, arg: 2, scope: !24, file: !10, type: !32)
+!24 = distinct !DISubprogram(name: "min<unsigned long long>", linkageName: "_ZN3__13minIyEERKT_S3_RS1_", line: 12, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 12, file: !1, scope: !25, type: !27, templateParams: !33, retainedNodes: !35)
+!25 = !DINamespace(name: "__1", scope: null)
+!26 = !DIFile(filename: "main.cpp", directory: "/Users/matt/ryan_bug")
+!27 = !DISubroutineType(types: !28)
+!28 = !{!29, !29, !32}
+!29 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !30)
+!30 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !31)
+!31 = !DIBasicType(tag: DW_TAG_base_type, name: "long long unsigned int", size: 64, align: 64, encoding: DW_ATE_unsigned)
+!32 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !31)
+!33 = !{!34}
+!34 = !DITemplateTypeParameter(name: "_Tp", type: !31)
+!35 = !{!36, !37}
+!36 = !DILocalVariable(name: "p1", line: 12, arg: 1, scope: !24, file: !10, type: !29)
+!37 = !DILocalVariable(name: "p2", line: 12, arg: 2, scope: !24, file: !10, type: !32)
+!38 = !DILocation(line: 33, scope: !9)
+!39 = !DILocation(line: 12, scope: !24, inlinedAt: !38)
+!40 = !DILocation(line: 9, scope: !41, inlinedAt: !59)
+!41 = distinct !DISubprogram(name: "min<unsigned long long, __1::A>", linkageName: "_ZN3__13minIyNS_1AEEERKT_S4_RS2_T0_", line: 7, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 8, file: !1, scope: !25, type: !42, templateParams: !53, retainedNodes: !55)
+!42 = !DISubroutineType(types: !43)
+!43 = !{!29, !29, !32, !44}
+!44 = !DICompositeType(tag: DW_TAG_structure_type, name: "A", size: 8, align: 8, file: !1, scope: !25, elements: !45)
+!45 = !{!46}
+!46 = !DISubprogram(name: "operator()", linkageName: "_ZN3__11AclERKiS2_", line: 1, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 1, file: !1, scope: !44, type: !47)
+!47 = !DISubroutineType(types: !48)
+!48 = !{!13, !49, !50, !50}
+!49 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !44)
+!50 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !51)
+!51 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !13)
+!53 = !{!34, !54}
+!54 = !DITemplateTypeParameter(name: "_Compare", type: !44)
+!55 = !{!56, !57, !58}
+!56 = !DILocalVariable(name: "p1", line: 7, arg: 1, scope: !41, file: !10, type: !29)
+!57 = !DILocalVariable(name: "p2", line: 7, arg: 2, scope: !41, file: !10, type: !32)
+!58 = !DILocalVariable(name: "p3", line: 8, arg: 3, scope: !41, file: !10, type: !44)
+!59 = !DILocation(line: 13, scope: !24, inlinedAt: !38)
+!63 = !{i32 undef}
+!64 = !DILocalVariable(name: "p1", line: 1, arg: 2, scope: !65, file: !10, type: !50)
+!65 = distinct !DISubprogram(name: "operator()", linkageName: "_ZN3__11AclERKiS2_", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 2, file: !1, scope: !25, type: !47, declaration: !46, retainedNodes: !66)
+!66 = !{!67, !69, !70}
+!67 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !65, type: !68)
+!68 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !44)
+!69 = !DILocalVariable(name: "p1", line: 1, arg: 2, scope: !65, file: !10, type: !50)
+!70 = !DILocalVariable(name: "", line: 2, arg: 3, scope: !65, file: !10, type: !50)
+!71 = !DILocation(line: 1, scope: !65, inlinedAt: !40)
+!72 = !{i32 1, !"Debug Info Version", i32 3}
+!73 = !DILocalVariable(name: "x", scope: !74, file: !1, line: 2, type: !13)
+!74 = distinct !DISubprogram(name: "IgnoreIntrinsicTest", linkageName: "IgnoreIntrinsicTest", scope: !1, file: !1, line: 1, type: !13, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !5)
+!75 = !DILocation(line: 2, column: 16, scope: !7)
diff --git a/llvm/test/Verifier/diexpression-entry-value-llvm-ir.ll b/llvm/test/Verifier/diexpression-entry-value-llvm-ir.ll
index 652e6667bfc5c..1a28f0ec519f7 100644
--- a/llvm/test/Verifier/diexpression-entry-value-llvm-ir.ll
+++ b/llvm/test/Verifier/diexpression-entry-value-llvm-ir.ll
@@ -1,9 +1,9 @@
; RUN: llvm-as -disable-output <%s 2>&1| FileCheck %s
-; CHECK-NOT: llvm.dbg.value
+; CHECK-NOT: #dbg_value
; CHECK: Entry values are only allowed in MIR unless they target a swiftasync Argument
-; CHECK: call void @llvm.dbg.value(metadata i32 %param, metadata !{{.*}}, metadata !DIExpression(DW_OP_LLVM_entry_value, 1))
-; CHECK-NOT: llvm.dbg.value
+; CHECK: #dbg_value(i32 %param, !{{.*}}, !DIExpression(DW_OP_LLVM_entry_value, 1),
+; CHECK-NOT: #dbg_value
; CHECK-NOT: Entry values are only allowed
; CHECK: warning: ignoring invalid debug info
diff --git a/llvm/test/Verifier/llvm.dbg.declare-address.ll b/llvm/test/Verifier/llvm.dbg.declare-address.ll
index 219f9ca0a6679..251526b4c321b 100644
--- a/llvm/test/Verifier/llvm.dbg.declare-address.ll
+++ b/llvm/test/Verifier/llvm.dbg.declare-address.ll
@@ -1,6 +1,6 @@
; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
-; CHECK: invalid llvm.dbg.declare intrinsic address/value
-; CHECK-NEXT: call void @llvm.dbg.declare({{.*}})
+; CHECK: invalid #dbg record address/value
+; CHECK-NEXT: #dbg_declare({{.*}})
; CHECK-NEXT: !""
; CHECK: warning: ignoring invalid debug info
diff --git a/llvm/test/Verifier/llvm.dbg.declare-expression.ll b/llvm/test/Verifier/llvm.dbg.declare-expression.ll
index 671ec21780088..04fd2876fc414 100644
--- a/llvm/test/Verifier/llvm.dbg.declare-expression.ll
+++ b/llvm/test/Verifier/llvm.dbg.declare-expression.ll
@@ -1,6 +1,6 @@
; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
-; CHECK: invalid llvm.dbg.declare intrinsic expression
-; CHECK-NEXT: call void @llvm.dbg.declare({{.*}})
+; CHECK: invalid #dbg record expression
+; CHECK-NEXT: #dbg_declare({{.*}})
; CHECK-NEXT: !""
; CHECK: warning: ignoring invalid debug info
diff --git a/llvm/test/Verifier/llvm.dbg.declare-variable.ll b/llvm/test/Verifier/llvm.dbg.declare-variable.ll
index 4f0ae4daa822f..4022a62c98d8e 100644
--- a/llvm/test/Verifier/llvm.dbg.declare-variable.ll
+++ b/llvm/test/Verifier/llvm.dbg.declare-variable.ll
@@ -1,6 +1,6 @@
; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
-; CHECK: invalid llvm.dbg.declare intrinsic variable
-; CHECK-NEXT: call void @llvm.dbg.declare({{.*}})
+; CHECK: invalid #dbg record variable
+; CHECK-NEXT: #dbg_declare({{.*}})
; CHECK-NEXT: !""
; CHECK: warning: ignoring invalid debug info
diff --git a/llvm/test/Verifier/llvm.dbg.intrinsic-dbg-attachment.ll b/llvm/test/Verifier/llvm.dbg.intrinsic-dbg-attachment.ll
index 5d82f490e055d..b1e22b20d0864 100644
--- a/llvm/test/Verifier/llvm.dbg.intrinsic-dbg-attachment.ll
+++ b/llvm/test/Verifier/llvm.dbg.intrinsic-dbg-attachment.ll
@@ -5,8 +5,8 @@ entry:
metadata ptr undef,
metadata !DILocalVariable(scope: !1),
metadata !DIExpression())
-; CHECK-LABEL: llvm.dbg.value intrinsic requires a !dbg attachment
-; CHECK-NEXT: call void @llvm.dbg.value({{.*}})
+; CHECK-LABEL: invalid #dbg record DILocation
+; CHECK-NEXT: #dbg_value({{.*}})
; CHECK-NEXT: label %entry
; CHECK-NEXT: ptr @foo
@@ -14,8 +14,8 @@ entry:
metadata ptr undef,
metadata !DILocalVariable(scope: !1),
metadata !DIExpression())
-; CHECK-LABEL: llvm.dbg.declare intrinsic requires a !dbg attachment
-; CHECK-NEXT: call void @llvm.dbg.declare({{.*}})
+; CHECK-LABEL: invalid #dbg record DILocation
+; CHECK-NEXT: #dbg_declare({{.*}})
; CHECK-NEXT: label %entry
; CHECK-NEXT: ptr @foo
@@ -24,8 +24,8 @@ entry:
metadata !DILocalVariable(scope: !1),
metadata !DIExpression()),
!dbg !DILocation(scope: !2)
-; CHECK-LABEL: mismatched subprogram between llvm.dbg.value variable and !dbg attachment
-; CHECK-NEXT: call void @llvm.dbg.value({{[^,]+}}, metadata ![[VAR:[0-9]+]], {{[^,]+}}), !dbg ![[LOC:[0-9]+]]
+; CHECK-LABEL: mismatched subprogram between #dbg record variable and DILocation
+; CHECK-NEXT: #dbg_value({{[^,]+}}, ![[VAR:[0-9]+]], {{[^,]+}}, ![[LOC:[0-9]+]])
; CHECK-NEXT: label %entry
; CHECK-NEXT: ptr @foo
; CHECK-NEXT: ![[VAR]] = !DILocalVariable({{.*}}scope: ![[VARSP:[0-9]+]]
@@ -38,8 +38,8 @@ entry:
metadata !DILocalVariable(scope: !1),
metadata !DIExpression()),
!dbg !DILocation(scope: !2)
-; CHECK-LABEL: mismatched subprogram between llvm.dbg.declare variable and !dbg attachment
-; CHECK-NEXT: call void @llvm.dbg.declare({{[^,]+}}, metadata ![[VAR:[0-9]+]], {{.*[^,]+}}), !dbg ![[LOC:[0-9]+]]
+; CHECK-LABEL: mismatched subprogram between #dbg record variable and DILocation
+; CHECK-NEXT: #dbg_declare({{[^,]+}}, ![[VAR:[0-9]+]], {{.*[^,]+}}, ![[LOC:[0-9]+]])
; CHECK-NEXT: label %entry
; CHECK-NEXT: ptr @foo
; CHECK-NEXT: ![[VAR]] = !DILocalVariable({{.*}}scope: ![[VARSP:[0-9]+]]
diff --git a/llvm/test/Verifier/llvm.dbg.value-expression.ll b/llvm/test/Verifier/llvm.dbg.value-expression.ll
index cc45af2e8e7cb..08f592d916bbe 100644
--- a/llvm/test/Verifier/llvm.dbg.value-expression.ll
+++ b/llvm/test/Verifier/llvm.dbg.value-expression.ll
@@ -1,6 +1,6 @@
; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
-; CHECK: invalid llvm.dbg.value intrinsic expression
-; CHECK-NEXT: call void @llvm.dbg.value({{.*}})
+; CHECK: invalid #dbg record expression
+; CHECK-NEXT: #dbg_value({{.*}})
; CHECK-NEXT: !""
; CHECK: warning: ignoring invalid debug info
diff --git a/llvm/test/Verifier/llvm.dbg.value-value.ll b/llvm/test/Verifier/llvm.dbg.value-value.ll
index 8b0ec1fed05c3..c390e530653cd 100644
--- a/llvm/test/Verifier/llvm.dbg.value-value.ll
+++ b/llvm/test/Verifier/llvm.dbg.value-value.ll
@@ -1,6 +1,6 @@
; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
-; CHECK: invalid llvm.dbg.value intrinsic address/value
-; CHECK-NEXT: call void @llvm.dbg.value({{.*}})
+; CHECK: invalid #dbg record address/value
+; CHECK-NEXT: #dbg_value({{.*}})
; CHECK-NEXT: !""
; CHECK: warning: ignoring invalid debug info
diff --git a/llvm/test/Verifier/llvm.dbg.value-variable.ll b/llvm/test/Verifier/llvm.dbg.value-variable.ll
index 4388e20797ce7..3a8fe3a6e1752 100644
--- a/llvm/test/Verifier/llvm.dbg.value-variable.ll
+++ b/llvm/test/Verifier/llvm.dbg.value-variable.ll
@@ -1,6 +1,6 @@
; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
-; CHECK: invalid llvm.dbg.value intrinsic variable
-; CHECK-NEXT: call void @llvm.dbg.value({{.*}})
+; CHECK: invalid #dbg record variable
+; CHECK-NEXT: #dbg_value({{.*}})
; CHECK-NEXT: !""
; CHECK: warning: ignoring invalid debug info
diff --git a/llvm/unittests/IR/DebugInfoTest.cpp b/llvm/unittests/IR/DebugInfoTest.cpp
index a888fd6c6cdc3..d7aa584bb8cb4 100644
--- a/llvm/unittests/IR/DebugInfoTest.cpp
+++ b/llvm/unittests/IR/DebugInfoTest.cpp
@@ -991,7 +991,6 @@ TEST(MetadataTest, ConvertDbgToDbgVariableRecord) {
Instruction *RetInst = &*std::next(FirstInst->getIterator());
// Set-up DbgMarkers in this block.
- ExitBlock->IsNewDbgInfoFormat = true;
ExitBlock->createMarker(FirstInst);
ExitBlock->createMarker(RetInst);
@@ -1127,7 +1126,6 @@ TEST(MetadataTest, DbgVariableRecordConversionRoutines) {
BasicBlock *BB1 = &F->getEntryBlock();
// First instruction should be a dbg.value.
EXPECT_TRUE(isa<DbgValueInst>(BB1->front()));
- EXPECT_FALSE(BB1->IsNewDbgInfoFormat);
// Validating the block for DbgVariableRecords / DbgMarkers shouldn't fail --
// there's no data stored right now.
bool BrokenDebugInfo = false;
@@ -1135,15 +1133,8 @@ TEST(MetadataTest, DbgVariableRecordConversionRoutines) {
EXPECT_FALSE(Error);
EXPECT_FALSE(BrokenDebugInfo);
- // Function and module should be marked as not having the new format too.
- EXPECT_FALSE(F->IsNewDbgInfoFormat);
- EXPECT_FALSE(M->IsNewDbgInfoFormat);
-
// Now convert.
M->convertToNewDbgValues();
- EXPECT_TRUE(M->IsNewDbgInfoFormat);
- EXPECT_TRUE(F->IsNewDbgInfoFormat);
- EXPECT_TRUE(BB1->IsNewDbgInfoFormat);
// There should now be no dbg.value instructions!
// Ensure the first instruction exists, the test all of them.
@@ -1180,7 +1171,6 @@ TEST(MetadataTest, DbgVariableRecordConversionRoutines) {
// There should be no DbgVariableRecords / DbgMarkers in the second block, but
// it should be marked as being in the new format.
BasicBlock *BB2 = BB1->getNextNode();
- EXPECT_TRUE(BB2->IsNewDbgInfoFormat);
for (auto &Inst : *BB2)
// Either there should be no marker, or it should be empty.
EXPECT_TRUE(!Inst.DebugMarker ||
@@ -1207,9 +1197,6 @@ TEST(MetadataTest, DbgVariableRecordConversionRoutines) {
// Convert everything back to the "old" format and ensure it's right.
M->convertFromNewDbgValues();
- EXPECT_FALSE(M->IsNewDbgInfoFormat);
- EXPECT_FALSE(F->IsNewDbgInfoFormat);
- EXPECT_FALSE(BB1->IsNewDbgInfoFormat);
EXPECT_EQ(BB1->size(), 4u);
ASSERT_TRUE(isa<DbgValueInst>(BB1->front()));
>From 3021087a6bea53b6fcbe7779cfe35ea165da2e60 Mon Sep 17 00:00:00 2001
From: Jeremy Morse <jeremy.morse at sony.com>
Date: Tue, 10 Jun 2025 12:53:12 +0100
Subject: [PATCH 2/7] Formatting, fix a comment, remove cruft from test
---
llvm/lib/IR/AsmWriter.cpp | 5 +--
llvm/lib/IR/AutoUpgrade.cpp | 6 +--
.../RemoveDI/invalid-dbg-declare-operands.ll | 40 ++-----------------
3 files changed, 8 insertions(+), 43 deletions(-)
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 598a8e141b1dd..4c784f97e4306 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -4876,11 +4876,10 @@ void AssemblyWriter::printDbgVariableRecord(const DbgVariableRecord &DVR) {
}
auto PrintOrNull = [&](Metadata *M) {
- if (!M) {
+ if (!M)
Out << "(null)";
- } else {
+ else
WriteAsOperandInternal(Out, M, WriterCtx, true);
- }
};
Out << "(";
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 58875e59c727d..542998d3252fb 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -4399,9 +4399,9 @@ template <typename MDType>
static MDType *unwrapMAVOp(CallBase *CI, unsigned Op) {
if (Op < CI->arg_size()) {
if (MetadataAsValue *MAV = dyn_cast<MetadataAsValue>(CI->getArgOperand(Op)))
- // Use a reinterpret cast rather than a safe default-to-null cast: the
- // autoupgrade process happens before the verifier, and thus there might
- // be some nonsense metadata in there.
+ // Use reinterpret_cast rather than dyn_cast because the autoupgrade
+ // process happens before the verifier, meaning we may see unexpected
+ // operands here.
return reinterpret_cast<MDType*>(MAV->getMetadata());
}
return nullptr;
diff --git a/llvm/test/Verifier/RemoveDI/invalid-dbg-declare-operands.ll b/llvm/test/Verifier/RemoveDI/invalid-dbg-declare-operands.ll
index 71a287f3293cc..cdc9d8df82aa7 100644
--- a/llvm/test/Verifier/RemoveDI/invalid-dbg-declare-operands.ll
+++ b/llvm/test/Verifier/RemoveDI/invalid-dbg-declare-operands.ll
@@ -15,35 +15,14 @@ target triple = "x86_64-unknown-linux-gnu"
declare void @llvm.dbg.declare(metadata, metadata, metadata)
; Function Attrs: alwaysinline nounwind sspstrong
-define i32 @_Z3foov() #0 !dbg !7 {
+define i32 @_Z3foov() !dbg !7 {
entry:
- %arr = alloca [10 x i32], align 16, !dbg !10
%sum = alloca i32, align 4, !dbg !11
call void @llvm.dbg.declare(metadata ptr %sum, metadata !26), !dbg !11
- store i32 5, ptr %arr, align 4, !dbg !12
- store i32 4, ptr %sum, align 4, !dbg !13
- %0 = load i32, ptr %sum, align 4, !dbg !14
- ret i32 %0, !dbg !15
+ ret i32 0, !dbg !15
}
-; Function Attrs: nounwind sspstrong
-define i32 @main() #1 !dbg !16 {
-entry:
- %retval = alloca i32, align 4, !dbg !17
- %i = alloca i32, align 4, !dbg !18
- store i32 0, ptr %retval, align 4, !dbg !19
- call void @_Z3barv(), !dbg !20
- %call = call i32 @_Z3foov(), !dbg !21
- store i32 %call, ptr %i, align 4, !dbg !22
- %0 = load i32, ptr %i, align 4, !dbg !23
- ret i32 %0, !dbg !24
-}
-
-declare void @_Z3barv() #2
-
-attributes #0 = { alwaysinline nounwind sspstrong "frame-pointer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
-attributes #1 = { nounwind sspstrong "frame-pointer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
-attributes #2 = { "frame-pointer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+declare void @_Z3barv()
!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!2}
@@ -60,21 +39,8 @@ attributes #2 = { "frame-pointer"="none" "less-precise-fpmad"="false" "no-infs-f
!7 = distinct !DISubprogram(name: "_Z3foov", linkageName: "_Z3foov", scope: null, file: !4, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !3, retainedNodes: !9)
!8 = !DISubroutineType(types: !9)
!9 = !{}
-!10 = !DILocation(line: 1, column: 1, scope: !7)
!11 = !DILocation(line: 2, column: 1, scope: !7)
-!12 = !DILocation(line: 3, column: 1, scope: !7)
-!13 = !DILocation(line: 4, column: 1, scope: !7)
-!14 = !DILocation(line: 5, column: 1, scope: !7)
!15 = !DILocation(line: 6, column: 1, scope: !7)
-!16 = distinct !DISubprogram(name: "main", linkageName: "main", scope: null, file: !4, line: 7, type: !8, scopeLine: 7, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !3, retainedNodes: !9)
-!17 = !DILocation(line: 7, column: 1, scope: !16)
-!18 = !DILocation(line: 8, column: 1, scope: !16)
-!19 = !DILocation(line: 9, column: 1, scope: !16)
-!20 = !DILocation(line: 10, column: 1, scope: !16)
-!21 = !DILocation(line: 11, column: 1, scope: !16)
-!22 = !DILocation(line: 12, column: 1, scope: !16)
-!23 = !DILocation(line: 13, column: 1, scope: !16)
-!24 = !DILocation(line: 14, column: 1, scope: !16)
!25 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!26 = !DILocalVariable(name: "b", scope: !7, file: !4, line: 1234, type: !25)
>From 8506550acee2ac0e6eb0251fe981fc06ff1cb255 Mon Sep 17 00:00:00 2001
From: Jeremy Morse <jeremy.morse at sony.com>
Date: Tue, 10 Jun 2025 14:05:06 +0100
Subject: [PATCH 3/7] Pass autoupgraded DbgRecords through pre-verifier
constructor
---
llvm/lib/IR/AsmWriter.cpp | 4 +-
llvm/lib/IR/AutoUpgrade.cpp | 79 +++++++++++--------
.../Verifier/llvm.dbg.declare-expression.ll | 1 -
.../Verifier/llvm.dbg.declare-variable.ll | 1 -
.../Verifier/llvm.dbg.value-expression.ll | 1 -
llvm/test/Verifier/llvm.dbg.value-variable.ll | 1 -
6 files changed, 49 insertions(+), 38 deletions(-)
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 4c784f97e4306..7828ba45ec27f 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1213,14 +1213,14 @@ void SlotTracker::processDbgRecordMetadata(const DbgRecord &DR) {
// DILocalVariable, DILocation, and DIAssignID fields, as the Value and
// Expression fields should only be printed inline and so do not use a slot.
// Note: The above doesn't apply for empty-metadata operands.
- if (auto *Empty = dyn_cast<MDNode>(DVR->getRawLocation()))
+ if (auto *Empty = dyn_cast_if_present<MDNode>(DVR->getRawLocation()))
CreateMetadataSlot(Empty);
if (DVR->getRawVariable())
CreateMetadataSlot(DVR->getRawVariable());
if (DVR->isDbgAssign()) {
if (auto *AssignID = DVR->getRawAssignID())
CreateMetadataSlot(cast<MDNode>(AssignID));
- if (auto *Empty = dyn_cast<MDNode>(DVR->getRawAddress()))
+ if (auto *Empty = dyn_cast_if_present<MDNode>(DVR->getRawAddress()))
CreateMetadataSlot(Empty);
}
} else if (const DbgLabelRecord *DLR = dyn_cast<const DbgLabelRecord>(&DR)) {
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 542998d3252fb..4862c8ce755fd 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -4394,26 +4394,32 @@ static Value *upgradeAMDGCNIntrinsicCall(StringRef Name, CallBase *CI,
return Builder.CreateBitCast(RMW, RetTy);
}
-/// Helper to unwrap intrinsic call MetadataAsValue operands.
-template <typename MDType>
-static MDType *unwrapMAVOp(CallBase *CI, unsigned Op) {
+/// Helper to unwrap intrinsic call MetadataAsValue operands. Return as a
+/// plain MDNode, as it's the verifiers job to check these are the correct
+/// types later.
+static MDNode *unwrapMAVOp(CallBase *CI, unsigned Op) {
if (Op < CI->arg_size()) {
- if (MetadataAsValue *MAV = dyn_cast<MetadataAsValue>(CI->getArgOperand(Op)))
- // Use reinterpret_cast rather than dyn_cast because the autoupgrade
- // process happens before the verifier, meaning we may see unexpected
- // operands here.
- return reinterpret_cast<MDType*>(MAV->getMetadata());
+ if (MetadataAsValue *MAV = dyn_cast<MetadataAsValue>(CI->getArgOperand(Op))) {
+ Metadata *MD = MAV->getMetadata();
+ if (isa<MDNode>(MD))
+ return reinterpret_cast<MDNode*>(MD);
+ }
}
return nullptr;
}
-static const DILocation *getDebugLocSafe(const Instruction *I) {
- MDNode *MD = I->getDebugLoc().getAsMDNode();
- // Use a C-style cast here rather than cast<DILocation>. The autoupgrader
- // runs before the verifier, so the Metadata could refer to anything. Allow
- // the verifier to detect and produce an error message, which will be much
- // more ergonomic to the user.
- return (const DILocation*)MD;
+/// Helper to unwrap Metadata MetadataAsValue operands, such as the Value field.
+static Metadata *unwrapMAVMetadataOp(CallBase *CI, unsigned Op) {
+ if (Op < CI->arg_size())
+ if (MetadataAsValue *MAV = dyn_cast<MetadataAsValue>(CI->getArgOperand(Op)))
+ return MAV->getMetadata();
+ return nullptr;
+}
+
+static MDNode *getDebugLocSafe(const Instruction *I) {
+ // The MDNode attached to this instruction might not be the correct type,
+ // as the verifier has not yet be run. Fetch it as a bare MDNode.
+ return I->getDebugLoc().getAsMDNode();
}
/// Convert debug intrinsic calls to non-instruction debug records.
@@ -4422,25 +4428,33 @@ static const DILocation *getDebugLocSafe(const Instruction *I) {
static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) {
DbgRecord *DR = nullptr;
if (Name == "label") {
- DR = new DbgLabelRecord(unwrapMAVOp<DILabel>(CI, 0), CI->getDebugLoc());
+ DR = DbgLabelRecord::createUnresolvedDbgLabelRecord(unwrapMAVOp(CI, 0), CI->getDebugLoc());
} else if (Name == "assign") {
- DR = new DbgVariableRecord(
- unwrapMAVOp<Metadata>(CI, 0), unwrapMAVOp<DILocalVariable>(CI, 1),
- unwrapMAVOp<DIExpression>(CI, 2), unwrapMAVOp<DIAssignID>(CI, 3),
- unwrapMAVOp<Metadata>(CI, 4), unwrapMAVOp<DIExpression>(CI, 5),
+ DR = DbgVariableRecord::createUnresolvedDbgVariableRecord(
+ DbgVariableRecord::LocationType::Assign,
+ unwrapMAVMetadataOp(CI, 0), unwrapMAVOp(CI, 1),
+ unwrapMAVOp(CI, 2), unwrapMAVOp(CI, 3),
+ unwrapMAVMetadataOp(CI, 4), /*The address is a Value ref, it will be stored as a Metadata */ unwrapMAVOp(CI, 5),
getDebugLocSafe(CI));
} else if (Name == "declare") {
- DR = new DbgVariableRecord(
- unwrapMAVOp<Metadata>(CI, 0), unwrapMAVOp<DILocalVariable>(CI, 1),
- unwrapMAVOp<DIExpression>(CI, 2), getDebugLocSafe(CI),
- DbgVariableRecord::LocationType::Declare);
+ DR = DbgVariableRecord::createUnresolvedDbgVariableRecord(
+ DbgVariableRecord::LocationType::Declare,
+ unwrapMAVMetadataOp(CI, 0), unwrapMAVOp(CI, 1),
+ unwrapMAVOp(CI, 2), nullptr, nullptr, nullptr,
+ getDebugLocSafe(CI));
} 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 DbgVariableRecord(unwrapMAVOp<Metadata>(CI, 0),
- unwrapMAVOp<DILocalVariable>(CI, 1), Expr,
- getDebugLocSafe(CI));
+ MDNode *ExprNode = unwrapMAVOp(CI, 2);
+ // Don't try to add something to the expression if it's not an expression.
+ // Instead, allow the verifier to fail later.
+ if (DIExpression *Expr = dyn_cast<DIExpression>(ExprNode)) {
+ ExprNode = DIExpression::append(Expr, dwarf::DW_OP_deref);
+ }
+ DR = DbgVariableRecord::createUnresolvedDbgVariableRecord(
+ DbgVariableRecord::LocationType::Value,
+ unwrapMAVMetadataOp(CI, 0),
+ unwrapMAVOp(CI, 1), ExprNode, nullptr, nullptr, nullptr,
+ getDebugLocSafe(CI));
} else if (Name == "value") {
// An old version of dbg.value had an extra offset argument.
unsigned VarOp = 1;
@@ -4453,9 +4467,10 @@ static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) {
VarOp = 2;
ExprOp = 3;
}
- DR = new DbgVariableRecord(
- unwrapMAVOp<Metadata>(CI, 0), unwrapMAVOp<DILocalVariable>(CI, VarOp),
- unwrapMAVOp<DIExpression>(CI, ExprOp), getDebugLocSafe(CI));
+ DR = DbgVariableRecord::createUnresolvedDbgVariableRecord(
+ DbgVariableRecord::LocationType::Value,
+ unwrapMAVMetadataOp(CI, 0), unwrapMAVOp(CI, VarOp),
+ unwrapMAVOp(CI, ExprOp), nullptr, nullptr, nullptr, getDebugLocSafe(CI));
}
assert(DR && "Unhandled intrinsic kind in upgrade to DbgRecord");
CI->getParent()->insertDbgRecordBefore(DR, CI->getIterator());
diff --git a/llvm/test/Verifier/llvm.dbg.declare-expression.ll b/llvm/test/Verifier/llvm.dbg.declare-expression.ll
index 04fd2876fc414..de65bb570677e 100644
--- a/llvm/test/Verifier/llvm.dbg.declare-expression.ll
+++ b/llvm/test/Verifier/llvm.dbg.declare-expression.ll
@@ -1,7 +1,6 @@
; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
; CHECK: invalid #dbg record expression
; CHECK-NEXT: #dbg_declare({{.*}})
-; CHECK-NEXT: !""
; CHECK: warning: ignoring invalid debug info
define void @foo(i32 %a) {
diff --git a/llvm/test/Verifier/llvm.dbg.declare-variable.ll b/llvm/test/Verifier/llvm.dbg.declare-variable.ll
index 4022a62c98d8e..a78bb12eb8b9c 100644
--- a/llvm/test/Verifier/llvm.dbg.declare-variable.ll
+++ b/llvm/test/Verifier/llvm.dbg.declare-variable.ll
@@ -1,7 +1,6 @@
; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
; CHECK: invalid #dbg record variable
; CHECK-NEXT: #dbg_declare({{.*}})
-; CHECK-NEXT: !""
; CHECK: warning: ignoring invalid debug info
define void @foo(i32 %a) {
diff --git a/llvm/test/Verifier/llvm.dbg.value-expression.ll b/llvm/test/Verifier/llvm.dbg.value-expression.ll
index 08f592d916bbe..92fd2add700ed 100644
--- a/llvm/test/Verifier/llvm.dbg.value-expression.ll
+++ b/llvm/test/Verifier/llvm.dbg.value-expression.ll
@@ -1,7 +1,6 @@
; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
; CHECK: invalid #dbg record expression
; CHECK-NEXT: #dbg_value({{.*}})
-; CHECK-NEXT: !""
; CHECK: warning: ignoring invalid debug info
define void @foo(i32 %a) {
diff --git a/llvm/test/Verifier/llvm.dbg.value-variable.ll b/llvm/test/Verifier/llvm.dbg.value-variable.ll
index 3a8fe3a6e1752..603a4b5c47e7d 100644
--- a/llvm/test/Verifier/llvm.dbg.value-variable.ll
+++ b/llvm/test/Verifier/llvm.dbg.value-variable.ll
@@ -1,7 +1,6 @@
; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
; CHECK: invalid #dbg record variable
; CHECK-NEXT: #dbg_value({{.*}})
-; CHECK-NEXT: !""
; CHECK: warning: ignoring invalid debug info
define void @foo(i32 %a) {
>From d41ece6a30cb753669c2318cd4058964f67e3155 Mon Sep 17 00:00:00 2001
From: Jeremy Morse <jeremy.morse at sony.com>
Date: Tue, 10 Jun 2025 14:11:46 +0100
Subject: [PATCH 4/7] Test for some more localisation of debug-info errors
---
llvm/test/Verifier/llvm.dbg.declare-variable.ll | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/llvm/test/Verifier/llvm.dbg.declare-variable.ll b/llvm/test/Verifier/llvm.dbg.declare-variable.ll
index a78bb12eb8b9c..601fab190d36b 100644
--- a/llvm/test/Verifier/llvm.dbg.declare-variable.ll
+++ b/llvm/test/Verifier/llvm.dbg.declare-variable.ll
@@ -1,12 +1,16 @@
; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
; CHECK: invalid #dbg record variable
; CHECK-NEXT: #dbg_declare({{.*}})
+; CHECK-NEXT: DISubprogram
; CHECK: warning: ignoring invalid debug info
+;; This test ensures we report an illegal variable as illegal, but also that
+;; the illegal MDNode is printed out (DISubprogram) to help localise.
+
define void @foo(i32 %a) {
entry:
%s = alloca i32
- call void @llvm.dbg.declare(metadata ptr %s, metadata !"", metadata !DIExpression()), !dbg !DILocation(scope: !1)
+ call void @llvm.dbg.declare(metadata ptr %s, metadata !1, metadata !DIExpression()), !dbg !DILocation(scope: !1)
ret void
}
>From add20db084227ad4c2043012dcf1a9152b92c21b Mon Sep 17 00:00:00 2001
From: Jeremy Morse <jeremy.morse at sony.com>
Date: Tue, 10 Jun 2025 14:28:21 +0100
Subject: [PATCH 5/7] Hark the herald clang-format sings...
---
llvm/lib/IR/AutoUpgrade.cpp | 36 ++++++++++++++++++------------------
llvm/lib/IR/Verifier.cpp | 13 ++++++++-----
2 files changed, 26 insertions(+), 23 deletions(-)
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 4862c8ce755fd..2e6293290b4f2 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -4399,10 +4399,11 @@ static Value *upgradeAMDGCNIntrinsicCall(StringRef Name, CallBase *CI,
/// types later.
static MDNode *unwrapMAVOp(CallBase *CI, unsigned Op) {
if (Op < CI->arg_size()) {
- if (MetadataAsValue *MAV = dyn_cast<MetadataAsValue>(CI->getArgOperand(Op))) {
+ if (MetadataAsValue *MAV =
+ dyn_cast<MetadataAsValue>(CI->getArgOperand(Op))) {
Metadata *MD = MAV->getMetadata();
if (isa<MDNode>(MD))
- return reinterpret_cast<MDNode*>(MD);
+ return reinterpret_cast<MDNode *>(MD);
}
}
return nullptr;
@@ -4428,19 +4429,19 @@ static MDNode *getDebugLocSafe(const Instruction *I) {
static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) {
DbgRecord *DR = nullptr;
if (Name == "label") {
- DR = DbgLabelRecord::createUnresolvedDbgLabelRecord(unwrapMAVOp(CI, 0), CI->getDebugLoc());
+ DR = DbgLabelRecord::createUnresolvedDbgLabelRecord(unwrapMAVOp(CI, 0),
+ CI->getDebugLoc());
} else if (Name == "assign") {
DR = DbgVariableRecord::createUnresolvedDbgVariableRecord(
- DbgVariableRecord::LocationType::Assign,
- unwrapMAVMetadataOp(CI, 0), unwrapMAVOp(CI, 1),
- unwrapMAVOp(CI, 2), unwrapMAVOp(CI, 3),
- unwrapMAVMetadataOp(CI, 4), /*The address is a Value ref, it will be stored as a Metadata */ unwrapMAVOp(CI, 5),
- getDebugLocSafe(CI));
+ DbgVariableRecord::LocationType::Assign, unwrapMAVMetadataOp(CI, 0),
+ unwrapMAVOp(CI, 1), unwrapMAVOp(CI, 2), unwrapMAVOp(CI, 3),
+ unwrapMAVMetadataOp(CI, 4),
+ /*The address is a Value ref, it will be stored as a Metadata */
+ unwrapMAVOp(CI, 5), getDebugLocSafe(CI));
} else if (Name == "declare") {
DR = DbgVariableRecord::createUnresolvedDbgVariableRecord(
- DbgVariableRecord::LocationType::Declare,
- unwrapMAVMetadataOp(CI, 0), unwrapMAVOp(CI, 1),
- unwrapMAVOp(CI, 2), nullptr, nullptr, nullptr,
+ DbgVariableRecord::LocationType::Declare, unwrapMAVMetadataOp(CI, 0),
+ unwrapMAVOp(CI, 1), unwrapMAVOp(CI, 2), nullptr, nullptr, nullptr,
getDebugLocSafe(CI));
} else if (Name == "addr") {
// Upgrade dbg.addr to dbg.value with DW_OP_deref.
@@ -4451,10 +4452,9 @@ static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) {
ExprNode = DIExpression::append(Expr, dwarf::DW_OP_deref);
}
DR = DbgVariableRecord::createUnresolvedDbgVariableRecord(
- DbgVariableRecord::LocationType::Value,
- unwrapMAVMetadataOp(CI, 0),
- unwrapMAVOp(CI, 1), ExprNode, nullptr, nullptr, nullptr,
- getDebugLocSafe(CI));
+ DbgVariableRecord::LocationType::Value, unwrapMAVMetadataOp(CI, 0),
+ unwrapMAVOp(CI, 1), ExprNode, nullptr, nullptr, nullptr,
+ getDebugLocSafe(CI));
} else if (Name == "value") {
// An old version of dbg.value had an extra offset argument.
unsigned VarOp = 1;
@@ -4468,9 +4468,9 @@ static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) {
ExprOp = 3;
}
DR = DbgVariableRecord::createUnresolvedDbgVariableRecord(
- DbgVariableRecord::LocationType::Value,
- unwrapMAVMetadataOp(CI, 0), unwrapMAVOp(CI, VarOp),
- unwrapMAVOp(CI, ExprOp), nullptr, nullptr, nullptr, getDebugLocSafe(CI));
+ DbgVariableRecord::LocationType::Value, unwrapMAVMetadataOp(CI, 0),
+ unwrapMAVOp(CI, VarOp), unwrapMAVOp(CI, ExprOp), nullptr, nullptr,
+ nullptr, getDebugLocSafe(CI));
}
assert(DR && "Unhandled intrinsic kind in upgrade to DbgRecord");
CI->getParent()->insertDbgRecordBefore(DR, CI->getIterator());
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 17e76902fc0b5..e40bdc51aa70d 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -6725,7 +6725,8 @@ void Verifier::visit(DbgVariableRecord &DVR) {
// Allow integers here to support inttoptr salvage.
Type *Ty = VAM->getValue()->getType();
CheckDI(Ty->isPointerTy() || Ty->isIntegerTy(),
- "location of #dbg_declare must be a pointer or int", &DVR, MD, BB, F);
+ "location of #dbg_declare must be a pointer or int", &DVR, MD, BB,
+ F);
}
} else if (auto *AL = dyn_cast<DIArgList>(MD)) {
visitDIArgList(*AL, F);
@@ -6736,12 +6737,14 @@ void Verifier::visit(DbgVariableRecord &DVR) {
visitMDNode(*DVR.getRawVariable(), AreDebugLocsAllowed::No);
CheckDI(isa_and_nonnull<DIExpression>(DVR.getRawExpression()),
- "invalid #dbg record expression", &DVR, DVR.getRawExpression(), BB, F);
+ "invalid #dbg record expression", &DVR, DVR.getRawExpression(), BB,
+ F);
visitMDNode(*DVR.getExpression(), AreDebugLocsAllowed::No);
if (DVR.isDbgAssign()) {
CheckDI(isa_and_nonnull<DIAssignID>(DVR.getRawAssignID()),
- "invalid #dbg_assign DIAssignID", &DVR, DVR.getRawAssignID(), BB, F);
+ "invalid #dbg_assign DIAssignID", &DVR, DVR.getRawAssignID(), BB,
+ F);
visitMDNode(*cast<DIAssignID>(DVR.getRawAssignID()),
AreDebugLocsAllowed::No);
@@ -6769,8 +6772,8 @@ void Verifier::visit(DbgVariableRecord &DVR) {
// This check is redundant with one in visitLocalVariable().
DILocalVariable *Var = DVR.getVariable();
- CheckDI(isType(Var->getRawType()), "invalid type ref", Var,
- Var->getRawType(), BB, F);
+ CheckDI(isType(Var->getRawType()), "invalid type ref", Var, Var->getRawType(),
+ BB, F);
auto *DLNode = DVR.getDebugLoc().getAsMDNode();
CheckDI(isa_and_nonnull<DILocation>(DLNode), "invalid #dbg record DILocation",
>From 4c75936b96bee4812bc30a4c04dfbaeba1ac6cd0 Mon Sep 17 00:00:00 2001
From: Jeremy Morse <jeremy.morse at sony.com>
Date: Wed, 11 Jun 2025 10:11:09 +0100
Subject: [PATCH 6/7] Strip cruft from another test
---
.../Verifier/dbg-declare-invalid-debug-loc.ll | 103 +++---------------
1 file changed, 16 insertions(+), 87 deletions(-)
diff --git a/llvm/test/Verifier/dbg-declare-invalid-debug-loc.ll b/llvm/test/Verifier/dbg-declare-invalid-debug-loc.ll
index 56f91b2b6b212..c521a9b8eb11b 100644
--- a/llvm/test/Verifier/dbg-declare-invalid-debug-loc.ll
+++ b/llvm/test/Verifier/dbg-declare-invalid-debug-loc.ll
@@ -5,109 +5,38 @@
; caught by the verifier.
;
; CHECK: invalid #dbg record DILocation
-; CHECK-NEXT: #dbg_declare(ptr %1, !61, !DIExpression(), !62)
-; CHECK-NEXT: !DISubprogram(name: "IgnoreIntrinsicTest",
+; CHECK-NEXT: #dbg_declare(ptr %1, ![[VAR:[0-9]+]], !DIExpression(), ![[PROG:[0-9]+]])
+; CHECK-NEXT: ![[PROG]] = distinct !DISubprogram(name: "IgnoreIntrinsicTest",
; CHECK-NEXT: label %0
; CHECK-NEXT: ptr @IgnoreIntrinsicTest
- at a = external global { i64, [56 x i8] }, align 32
-
-; Function Attrs: nounwind sspreq
-define i32 @_Z18read_response_sizev() #0 !dbg !9 {
-entry:
- tail call void @llvm.dbg.value(metadata !22, i64 0, metadata !23, metadata !DIExpression()), !dbg !39
- %0 = load i64, ptr @a, align 8, !dbg !40
- tail call void @llvm.dbg.value(metadata i32 undef, i64 0, metadata !64, metadata !DIExpression()), !dbg !71
- %1 = trunc i64 %0 to i32
- ret i32 %1
-}
+declare void @llvm.dbg.declare(metadata, metadata, metadata)
-define i32 @IgnoreIntrinsicTest() #1 {
+define i32 @IgnoreIntrinsicTest() !dbg !10 {
%1 = alloca i32, align 4
- call void @llvm.dbg.declare(metadata ptr %1, metadata !73, metadata !DIExpression()), !dbg !74
+ call void @llvm.dbg.declare(metadata ptr %1, metadata !14, metadata !DIExpression()), !dbg !10
store volatile i32 1, ptr %1, align 4
%2 = load volatile i32, ptr %1, align 4
%3 = mul nsw i32 %2, 42
ret i32 %3
}
-; Function Attrs: nounwind readnone
-declare void @llvm.dbg.value(metadata, i64, metadata, metadata)
-declare void @llvm.dbg.declare(metadata, metadata, metadata)
-
-attributes #0 = { sspreq }
-
!llvm.dbg.cu = !{!0}
-!llvm.module.flags = !{!21, !72}
+!llvm.module.flags = !{!8, !9}
-!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.4 ", isOptimized: true, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !5, globals: !20, imports: !5)
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.4 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !5, globals: !5, imports: !5)
!1 = !DIFile(filename: "<unknown>", directory: "/Users/matt/ryan_bug")
!2 = !{!3}
-!3 = !DICompositeType(tag: DW_TAG_enumeration_type, line: 20, size: 32, align: 32, file: !1, scope: !4, elements: !6)
-!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "C", line: 19, size: 8, align: 8, file: !1, elements: !5)
+!3 = !DICompositeType(tag: DW_TAG_enumeration_type, scope: !4, file: !1, line: 20, size: 32, align: 32, elements: !6)
+!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "C", file: !1, line: 19, size: 8, align: 8, elements: !5)
!5 = !{}
!6 = !{!7}
-!7 = !DIEnumerator(name: "max_frame_size", value: 0) ; [ DW_TAG_enumerator ] [max_frame_size :: 0]
-!9 = distinct !DISubprogram(name: "read_response_size", linkageName: "_Z18read_response_sizev", line: 27, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 27, file: !1, scope: !10, type: !11, retainedNodes: !14)
-!10 = !DIFile(filename: "<unknown>", directory: "/Users/matt/ryan_bug")
+!7 = !DIEnumerator(name: "max_frame_size", value: 0)
+!8 = !{i32 2, !"Dwarf Version", i32 2}
+!9 = !{i32 1, !"Debug Info Version", i32 3}
+!10 = distinct !DISubprogram(name: "IgnoreIntrinsicTest", linkageName: "IgnoreIntrinsicTest", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !5)
!11 = !DISubroutineType(types: !12)
!12 = !{!13}
-!13 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
-!14 = !{!15, !19}
-!15 = !DILocalVariable(name: "b", line: 28, scope: !9, file: !10, type: !16)
-!16 = !DICompositeType(tag: DW_TAG_structure_type, name: "B", line: 16, size: 32, align: 32, file: !1, elements: !17)
-!17 = !{!18}
-!18 = !DIDerivedType(tag: DW_TAG_member, name: "end_of_file", line: 17, size: 32, align: 32, file: !1, scope: !16, baseType: !13)
-!19 = !DILocalVariable(name: "c", line: 29, scope: !9, file: !10, type: !13)
-!20 = !{}
-!21 = !{i32 2, !"Dwarf Version", i32 2}
-!22 = !{ptr @a}
-!23 = !DILocalVariable(name: "p2", line: 12, arg: 2, scope: !24, file: !10, type: !32)
-!24 = distinct !DISubprogram(name: "min<unsigned long long>", linkageName: "_ZN3__13minIyEERKT_S3_RS1_", line: 12, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 12, file: !1, scope: !25, type: !27, templateParams: !33, retainedNodes: !35)
-!25 = !DINamespace(name: "__1", scope: null)
-!26 = !DIFile(filename: "main.cpp", directory: "/Users/matt/ryan_bug")
-!27 = !DISubroutineType(types: !28)
-!28 = !{!29, !29, !32}
-!29 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !30)
-!30 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !31)
-!31 = !DIBasicType(tag: DW_TAG_base_type, name: "long long unsigned int", size: 64, align: 64, encoding: DW_ATE_unsigned)
-!32 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !31)
-!33 = !{!34}
-!34 = !DITemplateTypeParameter(name: "_Tp", type: !31)
-!35 = !{!36, !37}
-!36 = !DILocalVariable(name: "p1", line: 12, arg: 1, scope: !24, file: !10, type: !29)
-!37 = !DILocalVariable(name: "p2", line: 12, arg: 2, scope: !24, file: !10, type: !32)
-!38 = !DILocation(line: 33, scope: !9)
-!39 = !DILocation(line: 12, scope: !24, inlinedAt: !38)
-!40 = !DILocation(line: 9, scope: !41, inlinedAt: !59)
-!41 = distinct !DISubprogram(name: "min<unsigned long long, __1::A>", linkageName: "_ZN3__13minIyNS_1AEEERKT_S4_RS2_T0_", line: 7, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 8, file: !1, scope: !25, type: !42, templateParams: !53, retainedNodes: !55)
-!42 = !DISubroutineType(types: !43)
-!43 = !{!29, !29, !32, !44}
-!44 = !DICompositeType(tag: DW_TAG_structure_type, name: "A", size: 8, align: 8, file: !1, scope: !25, elements: !45)
-!45 = !{!46}
-!46 = !DISubprogram(name: "operator()", linkageName: "_ZN3__11AclERKiS2_", line: 1, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 1, file: !1, scope: !44, type: !47)
-!47 = !DISubroutineType(types: !48)
-!48 = !{!13, !49, !50, !50}
-!49 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !44)
-!50 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !51)
-!51 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !13)
-!53 = !{!34, !54}
-!54 = !DITemplateTypeParameter(name: "_Compare", type: !44)
-!55 = !{!56, !57, !58}
-!56 = !DILocalVariable(name: "p1", line: 7, arg: 1, scope: !41, file: !10, type: !29)
-!57 = !DILocalVariable(name: "p2", line: 7, arg: 2, scope: !41, file: !10, type: !32)
-!58 = !DILocalVariable(name: "p3", line: 8, arg: 3, scope: !41, file: !10, type: !44)
-!59 = !DILocation(line: 13, scope: !24, inlinedAt: !38)
-!63 = !{i32 undef}
-!64 = !DILocalVariable(name: "p1", line: 1, arg: 2, scope: !65, file: !10, type: !50)
-!65 = distinct !DISubprogram(name: "operator()", linkageName: "_ZN3__11AclERKiS2_", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 2, file: !1, scope: !25, type: !47, declaration: !46, retainedNodes: !66)
-!66 = !{!67, !69, !70}
-!67 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !65, type: !68)
-!68 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !44)
-!69 = !DILocalVariable(name: "p1", line: 1, arg: 2, scope: !65, file: !10, type: !50)
-!70 = !DILocalVariable(name: "", line: 2, arg: 3, scope: !65, file: !10, type: !50)
-!71 = !DILocation(line: 1, scope: !65, inlinedAt: !40)
-!72 = !{i32 1, !"Debug Info Version", i32 3}
-!73 = !DILocalVariable(name: "x", scope: !74, file: !1, line: 2, type: !13)
-!74 = distinct !DISubprogram(name: "IgnoreIntrinsicTest", linkageName: "IgnoreIntrinsicTest", scope: !1, file: !1, line: 1, type: !13, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !5)
-!75 = !DILocation(line: 2, column: 16, scope: !7)
+!13 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
+!14 = !DILocalVariable(name: "x", scope: !10, file: !1, line: 2, type: !13)
+!15 = !DILocation(line: 2, column: 16, scope: !10)
>From bf1e1689b25af485c7f649af337ab65b939d93d7 Mon Sep 17 00:00:00 2001
From: Jeremy Morse <jeremy.morse at sony.com>
Date: Wed, 11 Jun 2025 10:33:45 +0100
Subject: [PATCH 7/7] Spelling, and avoid an un-necessary reinterpret cast
---
llvm/lib/IR/AutoUpgrade.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 2e6293290b4f2..cb90af36f3d9f 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -4395,15 +4395,14 @@ static Value *upgradeAMDGCNIntrinsicCall(StringRef Name, CallBase *CI,
}
/// Helper to unwrap intrinsic call MetadataAsValue operands. Return as a
-/// plain MDNode, as it's the verifiers job to check these are the correct
+/// plain MDNode, as it's the verifier's job to check these are the correct
/// types later.
static MDNode *unwrapMAVOp(CallBase *CI, unsigned Op) {
if (Op < CI->arg_size()) {
if (MetadataAsValue *MAV =
dyn_cast<MetadataAsValue>(CI->getArgOperand(Op))) {
Metadata *MD = MAV->getMetadata();
- if (isa<MDNode>(MD))
- return reinterpret_cast<MDNode *>(MD);
+ return dyn_cast_if_present<MDNode>(MD);
}
}
return nullptr;
More information about the llvm-commits
mailing list