Skip to content

Commit 11e2a15

Browse files
OCHyamstru
authored andcommitted
[RemoveDIs] Fix spliceDebugInfo splice-to-end edge case (#105671)
Fix #105571 which demonstrates an end() iterator dereference when performing a non-empty splice to end() from a region that ends at Src::end(). Rather than calling Instruction::adoptDbgRecords from Dest, create a marker (which takes an iterator) and absorbDebugValues onto that. The "absorb" variant doesn't clean up the source marker, which in this case we know is a trailing marker, so we have to do that manually. (cherry picked from commit 43661a1)
1 parent 64015ee commit 11e2a15

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

llvm/lib/IR/BasicBlock.cpp

+10-2
Original file line numberDiff line numberDiff line change
@@ -975,8 +975,16 @@ void BasicBlock::spliceDebugInfoImpl(BasicBlock::iterator Dest, BasicBlock *Src,
975975
if (ReadFromTail && Src->getMarker(Last)) {
976976
DbgMarker *FromLast = Src->getMarker(Last);
977977
if (LastIsEnd) {
978-
Dest->adoptDbgRecords(Src, Last, true);
979-
// adoptDbgRecords will release any trailers.
978+
if (Dest == end()) {
979+
// Abosrb the trailing markers from Src.
980+
assert(FromLast == Src->getTrailingDbgRecords());
981+
createMarker(Dest)->absorbDebugValues(*FromLast, true);
982+
FromLast->eraseFromParent();
983+
Src->deleteTrailingDbgRecords();
984+
} else {
985+
// adoptDbgRecords will release any trailers.
986+
Dest->adoptDbgRecords(Src, Last, true);
987+
}
980988
assert(!Src->getTrailingDbgRecords());
981989
} else {
982990
// FIXME: can we use adoptDbgRecords here to reduce allocations?

llvm/unittests/IR/BasicBlockDbgInfoTest.cpp

+52
Original file line numberDiff line numberDiff line change
@@ -1525,4 +1525,56 @@ TEST(BasicBlockDbgInfoTest, DbgMoveToEnd) {
15251525
EXPECT_FALSE(Ret->hasDbgRecords());
15261526
}
15271527

1528+
TEST(BasicBlockDbgInfoTest, CloneTrailingRecordsToEmptyBlock) {
1529+
LLVMContext C;
1530+
std::unique_ptr<Module> M = parseIR(C, R"(
1531+
define i16 @foo(i16 %a) !dbg !6 {
1532+
entry:
1533+
%b = add i16 %a, 0
1534+
#dbg_value(i16 %b, !9, !DIExpression(), !11)
1535+
ret i16 0, !dbg !11
1536+
}
1537+
1538+
!llvm.dbg.cu = !{!0}
1539+
!llvm.module.flags = !{!5}
1540+
1541+
!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
1542+
!1 = !DIFile(filename: "t.ll", directory: "/")
1543+
!2 = !{}
1544+
!5 = !{i32 2, !"Debug Info Version", i32 3}
1545+
!6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
1546+
!7 = !DISubroutineType(types: !2)
1547+
!8 = !{!9}
1548+
!9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
1549+
!10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)
1550+
!11 = !DILocation(line: 1, column: 1, scope: !6)
1551+
)");
1552+
ASSERT_TRUE(M);
1553+
1554+
Function *F = M->getFunction("foo");
1555+
BasicBlock &BB = F->getEntryBlock();
1556+
// Start with no trailing records.
1557+
ASSERT_FALSE(BB.getTrailingDbgRecords());
1558+
1559+
BasicBlock::iterator Ret = std::prev(BB.end());
1560+
BasicBlock::iterator B = std::prev(Ret);
1561+
1562+
// Delete terminator which has debug records: we now get trailing records.
1563+
Ret->eraseFromParent();
1564+
EXPECT_TRUE(BB.getTrailingDbgRecords());
1565+
1566+
BasicBlock *NewBB = BasicBlock::Create(C, "NewBB", F);
1567+
NewBB->splice(NewBB->end(), &BB, B, BB.end());
1568+
1569+
// The trailing records should've been absorbed into NewBB.
1570+
EXPECT_FALSE(BB.getTrailingDbgRecords());
1571+
EXPECT_TRUE(NewBB->getTrailingDbgRecords());
1572+
if (DbgMarker *Trailing = NewBB->getTrailingDbgRecords()) {
1573+
EXPECT_EQ(llvm::range_size(Trailing->getDbgRecordRange()), 1u);
1574+
// Drop the trailing records now, to prevent a cleanup assertion.
1575+
Trailing->eraseFromParent();
1576+
NewBB->deleteTrailingDbgRecords();
1577+
}
1578+
}
1579+
15281580
} // End anonymous namespace.

0 commit comments

Comments
 (0)