Skip to content

Commit 600c129

Browse files
authored
[DebugInfo][RemoveDIs] Reverse order of DPValues from findDbgUsers (#74099)
The order of dbg.value intrinsics appearing in the output can affect the order of tables in DWARF sections. This means that DPValues, our dbg.value replacement, needs to obey the same ordering rules. For dbg.values returned by findDbgUsers it's reverse order of creation (due to how they're put on use-lists). Produce that order from findDbgUsers for DPValues. I've got a few IR files where the order of dbg.values flips, but it's a fragile test -- ultimately it needs the number of times a DPValue is handled by findDbgValues to be odd.
1 parent 7931426 commit 600c129

File tree

3 files changed

+72
-9
lines changed

3 files changed

+72
-9
lines changed

llvm/lib/IR/Metadata.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,13 @@ SmallVector<DPValue *> ReplaceableMetadataImpl::getAllDPValueUsers() {
249249
continue;
250250
DPVUsersWithID.push_back(&UseMap[Pair.first]);
251251
}
252+
// Order DPValue users in reverse-creation order. Normal dbg.value users
253+
// of MetadataAsValues are ordered by their UseList, i.e. reverse order of
254+
// when they were added: we need to replicate that here. The structure of
255+
// debug-info output depends on the ordering of intrinsics, thus we need
256+
// to keep them consistent for comparisons sake.
252257
llvm::sort(DPVUsersWithID, [](auto UserA, auto UserB) {
253-
return UserA->second < UserB->second;
258+
return UserA->second > UserB->second;
254259
});
255260
SmallVector<DPValue *> DPVUsers;
256261
for (auto UserWithID : DPVUsersWithID)

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2587,14 +2587,7 @@ static bool rewriteDebugUsers(
25872587
}
25882588

25892589
// DPValue implementation of the above.
2590-
// RemoveDIs misery: The above loop of intrinsic-users are ordered by the
2591-
// use-list of the corresponding metadata-as-value: in reverse order of when
2592-
// they were added. Wheras DPUsers are ordered by when they were added to
2593-
// the replaceable-metadata map, i.e., in the order they were added. Thus to
2594-
// have matching orders between the two, we have to reverse here. For
2595-
// RemoveDIs we might in the long run need to consider whether this implicit
2596-
// ordering is relied upon by any other part of LLVM.
2597-
for (auto *DPV : llvm::reverse(DPUsers)) {
2590+
for (auto *DPV : DPUsers) {
25982591
Instruction *MarkedInstr = DPV->getMarker()->MarkedInstr;
25992592
Instruction *NextNonDebug = MarkedInstr;
26002593
// The next instruction might still be a dbg.declare, skip over it.

llvm/unittests/IR/DebugInfoTest.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,71 @@ TEST(MetadataTest, DeleteInstUsedByDPValue) {
284284
UseNewDbgInfoFormat = OldDbgValueMode;
285285
}
286286

287+
// Ensure that the order of dbg.value intrinsics returned by findDbgValues, and
288+
// their corresponding DPValue representation, are consistent.
289+
TEST(MetadataTest, OrderingOfDPValues) {
290+
LLVMContext C;
291+
std::unique_ptr<Module> M = parseIR(C, R"(
292+
define i16 @f(i16 %a) !dbg !6 {
293+
%b = add i16 %a, 1, !dbg !11
294+
call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11
295+
call void @llvm.dbg.value(metadata i16 %b, metadata !12, metadata !DIExpression()), !dbg !11
296+
ret i16 0, !dbg !11
297+
}
298+
declare void @llvm.dbg.value(metadata, metadata, metadata) #0
299+
attributes #0 = { nounwind readnone speculatable willreturn }
300+
301+
!llvm.dbg.cu = !{!0}
302+
!llvm.module.flags = !{!5}
303+
304+
!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
305+
!1 = !DIFile(filename: "t.ll", directory: "/")
306+
!2 = !{}
307+
!5 = !{i32 2, !"Debug Info Version", i32 3}
308+
!6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
309+
!7 = !DISubroutineType(types: !2)
310+
!8 = !{!9}
311+
!9 = !DILocalVariable(name: "foo", scope: !6, file: !1, line: 1, type: !10)
312+
!10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)
313+
!11 = !DILocation(line: 1, column: 1, scope: !6)
314+
!12 = !DILocalVariable(name: "bar", scope: !6, file: !1, line: 1, type: !10)
315+
)");
316+
317+
bool OldDbgValueMode = UseNewDbgInfoFormat;
318+
UseNewDbgInfoFormat = true;
319+
Instruction &I = *M->getFunction("f")->getEntryBlock().getFirstNonPHI();
320+
321+
SmallVector<DbgValueInst *, 2> DVIs;
322+
SmallVector<DPValue *, 2> DPVs;
323+
findDbgValues(DVIs, &I, &DPVs);
324+
ASSERT_EQ(DVIs.size(), 2u);
325+
ASSERT_EQ(DPVs.size(), 0u);
326+
327+
// The correct order of dbg.values is given by their use-list, which becomes
328+
// the reverse order of creation. Thus the dbg.values should come out as
329+
// "bar" and then "foo".
330+
DILocalVariable *Var0 = DVIs[0]->getVariable();
331+
EXPECT_TRUE(Var0->getName() == "bar");
332+
DILocalVariable *Var1 = DVIs[1]->getVariable();
333+
EXPECT_TRUE(Var1->getName() == "foo");
334+
335+
// Now try again, but in DPValue form.
336+
DVIs.clear();
337+
338+
M->convertToNewDbgValues();
339+
findDbgValues(DVIs, &I, &DPVs);
340+
ASSERT_EQ(DVIs.size(), 0u);
341+
ASSERT_EQ(DPVs.size(), 2u);
342+
343+
Var0 = DPVs[0]->getVariable();
344+
EXPECT_TRUE(Var0->getName() == "bar");
345+
Var1 = DPVs[1]->getVariable();
346+
EXPECT_TRUE(Var1->getName() == "foo");
347+
348+
M->convertFromNewDbgValues();
349+
UseNewDbgInfoFormat = OldDbgValueMode;
350+
}
351+
287352
TEST(DIBuiler, CreateFile) {
288353
LLVMContext Ctx;
289354
std::unique_ptr<Module> M(new Module("MyModule", Ctx));

0 commit comments

Comments
 (0)