Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions llvm/lib/IR/AsmWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
79 changes: 47 additions & 32 deletions llvm/lib/IR/AutoUpgrade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;
Expand All @@ -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());
Expand Down
1 change: 0 additions & 1 deletion llvm/test/Verifier/llvm.dbg.declare-expression.ll
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down
1 change: 0 additions & 1 deletion llvm/test/Verifier/llvm.dbg.declare-variable.ll
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down
1 change: 0 additions & 1 deletion llvm/test/Verifier/llvm.dbg.value-expression.ll
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down
1 change: 0 additions & 1 deletion llvm/test/Verifier/llvm.dbg.value-variable.ll
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down
Loading