1 //===- llvm/unittest/IR/DebugInfo.cpp - DebugInfo tests -------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/IR/DebugInfo.h"
10 #include "llvm/ADT/APSInt.h"
11 #include "llvm/AsmParser/Parser.h"
12 #include "llvm/IR/DIBuilder.h"
13 #include "llvm/IR/DebugInfoMetadata.h"
14 #include "llvm/IR/DebugProgramInstruction.h"
15 #include "llvm/IR/IRBuilder.h"
16 #include "llvm/IR/IntrinsicInst.h"
17 #include "llvm/IR/LLVMContext.h"
18 #include "llvm/IR/Metadata.h"
19 #include "llvm/IR/Module.h"
20 #include "llvm/IR/Verifier.h"
21 #include "llvm/Support/SourceMgr.h"
22 #include "llvm/Transforms/Utils/Local.h"
23 #include "gtest/gtest.h"
27 extern cl::opt
<bool> UseNewDbgInfoFormat
;
29 static std::unique_ptr
<Module
> parseIR(LLVMContext
&C
, const char *IR
) {
31 std::unique_ptr
<Module
> Mod
= parseAssemblyString(IR
, Err
, C
);
33 Err
.print("DebugInfoTest", errs());
39 TEST(DINodeTest
, getFlag
) {
41 EXPECT_EQ(DINode::FlagPublic
, DINode::getFlag("DIFlagPublic"));
42 EXPECT_EQ(DINode::FlagProtected
, DINode::getFlag("DIFlagProtected"));
43 EXPECT_EQ(DINode::FlagPrivate
, DINode::getFlag("DIFlagPrivate"));
44 EXPECT_EQ(DINode::FlagVector
, DINode::getFlag("DIFlagVector"));
45 EXPECT_EQ(DINode::FlagRValueReference
,
46 DINode::getFlag("DIFlagRValueReference"));
48 // FlagAccessibility shouldn't work.
49 EXPECT_EQ(0u, DINode::getFlag("DIFlagAccessibility"));
51 // Some other invalid strings.
52 EXPECT_EQ(0u, DINode::getFlag("FlagVector"));
53 EXPECT_EQ(0u, DINode::getFlag("Vector"));
54 EXPECT_EQ(0u, DINode::getFlag("other things"));
55 EXPECT_EQ(0u, DINode::getFlag("DIFlagOther"));
58 TEST(DINodeTest
, getFlagString
) {
60 EXPECT_EQ(StringRef("DIFlagPublic"),
61 DINode::getFlagString(DINode::FlagPublic
));
62 EXPECT_EQ(StringRef("DIFlagProtected"),
63 DINode::getFlagString(DINode::FlagProtected
));
64 EXPECT_EQ(StringRef("DIFlagPrivate"),
65 DINode::getFlagString(DINode::FlagPrivate
));
66 EXPECT_EQ(StringRef("DIFlagVector"),
67 DINode::getFlagString(DINode::FlagVector
));
68 EXPECT_EQ(StringRef("DIFlagRValueReference"),
69 DINode::getFlagString(DINode::FlagRValueReference
));
71 // FlagAccessibility actually equals FlagPublic.
72 EXPECT_EQ(StringRef("DIFlagPublic"),
73 DINode::getFlagString(DINode::FlagAccessibility
));
75 // Some other invalid flags.
76 EXPECT_EQ(StringRef(),
77 DINode::getFlagString(DINode::FlagPublic
| DINode::FlagVector
));
78 EXPECT_EQ(StringRef(), DINode::getFlagString(DINode::FlagFwdDecl
|
79 DINode::FlagArtificial
));
80 EXPECT_EQ(StringRef(),
81 DINode::getFlagString(static_cast<DINode::DIFlags
>(0xffff)));
84 TEST(DINodeTest
, splitFlags
) {
86 #define CHECK_SPLIT(FLAGS, VECTOR, REMAINDER) \
88 SmallVector<DINode::DIFlags, 8> V; \
89 EXPECT_EQ(REMAINDER, DINode::splitFlags(FLAGS, V)); \
90 EXPECT_TRUE(ArrayRef(V).equals(VECTOR)); \
92 CHECK_SPLIT(DINode::FlagPublic
, {DINode::FlagPublic
}, DINode::FlagZero
);
93 CHECK_SPLIT(DINode::FlagProtected
, {DINode::FlagProtected
}, DINode::FlagZero
);
94 CHECK_SPLIT(DINode::FlagPrivate
, {DINode::FlagPrivate
}, DINode::FlagZero
);
95 CHECK_SPLIT(DINode::FlagVector
, {DINode::FlagVector
}, DINode::FlagZero
);
96 CHECK_SPLIT(DINode::FlagRValueReference
, {DINode::FlagRValueReference
},
98 DINode::DIFlags Flags
[] = {DINode::FlagFwdDecl
, DINode::FlagVector
};
99 CHECK_SPLIT(DINode::FlagFwdDecl
| DINode::FlagVector
, Flags
,
101 CHECK_SPLIT(DINode::FlagZero
, {}, DINode::FlagZero
);
105 TEST(StripTest
, LoopMetadata
) {
107 std::unique_ptr
<Module
> M
= parseIR(C
, R
"(
108 define void @f() !dbg !5 {
109 ret void, !dbg !10, !llvm.loop !11
113 !llvm.debugify = !{!3, !3}
114 !llvm.module.flags = !{!4}
116 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify
", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
117 !1 = !DIFile(filename: "loop
.ll
", directory: "/")
120 !4 = !{i32 2, !"Debug Info Version
", i32 3}
121 !5 = distinct !DISubprogram(name: "f
", linkageName: "f
", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !7)
122 !6 = !DISubroutineType(types: !2)
124 !8 = !DILocalVariable(name: "1", scope: !5, file: !1, line: 1, type: !9)
125 !9 = !DIBasicType(name: "ty32
", size: 32, encoding: DW_ATE_unsigned)
126 !10 = !DILocation(line: 1, column: 1, scope: !5)
127 !11 = distinct !{!11, !10, !10}
130 // Look up the debug info emission kind for the CU via the loop metadata
131 // attached to the terminator. If, when stripping non-line table debug info,
132 // we update the terminator's metadata correctly, we should be able to
133 // observe the change in emission kind for the CU.
134 auto getEmissionKind
= [&]() {
135 Instruction
&I
= *M
->getFunction("f")->getEntryBlock().getFirstNonPHI();
136 MDNode
*LoopMD
= I
.getMetadata(LLVMContext::MD_loop
);
137 return cast
<DILocation
>(LoopMD
->getOperand(1))
144 EXPECT_EQ(getEmissionKind(), DICompileUnit::FullDebug
);
146 bool Changed
= stripNonLineTableDebugInfo(*M
);
147 EXPECT_TRUE(Changed
);
149 EXPECT_EQ(getEmissionKind(), DICompileUnit::LineTablesOnly
);
151 bool BrokenDebugInfo
= false;
152 bool HardError
= verifyModule(*M
, &errs(), &BrokenDebugInfo
);
153 EXPECT_FALSE(HardError
);
154 EXPECT_FALSE(BrokenDebugInfo
);
157 TEST(MetadataTest
, DeleteInstUsedByDbgValue
) {
159 std::unique_ptr
<Module
> M
= parseIR(C
, R
"(
160 define i16 @f(i16 %a) !dbg !6 {
161 %b = add i16 %a, 1, !dbg !11
162 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11
165 declare void @llvm.dbg.value(metadata, metadata, metadata) #0
166 attributes #0 = { nounwind readnone speculatable willreturn }
169 !llvm.module.flags = !{!5}
171 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify
", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
172 !1 = !DIFile(filename: "t
.ll
", directory: "/")
174 !5 = !{i32 2, !"Debug Info Version
", i32 3}
175 !6 = distinct !DISubprogram(name: "foo
", linkageName: "foo
", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
176 !7 = !DISubroutineType(types: !2)
178 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
179 !10 = !DIBasicType(name: "ty16
", size: 16, encoding: DW_ATE_unsigned)
180 !11 = !DILocation(line: 1, column: 1, scope: !6)
184 Instruction
&I
= *M
->getFunction("f")->getEntryBlock().getFirstNonPHI();
186 // Find the dbg.value using %b.
187 SmallVector
<DbgValueInst
*, 1> DVIs
;
188 findDbgValues(DVIs
, &I
);
190 // Delete %b. The dbg.value should now point to undef.
192 EXPECT_EQ(DVIs
[0]->getNumVariableLocationOps(), 1u);
193 EXPECT_TRUE(isa
<UndefValue
>(DVIs
[0]->getValue(0)));
196 TEST(DbgVariableIntrinsic
, EmptyMDIsKillLocation
) {
198 std::unique_ptr
<Module
> M
= parseIR(Ctx
, R
"(
199 define dso_local void @fun() local_unnamed_addr #0 !dbg !9 {
201 call void @llvm.dbg.declare(metadata !{}, metadata !13, metadata !DIExpression()), !dbg !16
205 declare void @llvm.dbg.declare(metadata, metadata, metadata)
208 !llvm.module.flags = !{!2, !3}
211 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version
16.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
212 !1 = !DIFile(filename: "test
.c
", directory: "/")
213 !2 = !{i32 7, !"Dwarf Version
", i32 5}
214 !3 = !{i32 2, !"Debug Info Version
", i32 3}
215 !8 = !{!"clang version
16.0.0"}
216 !9 = distinct !DISubprogram(name: "fun
", scope: !1, file: !1, line: 1, type: !10, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
217 !10 = !DISubroutineType(types: !11)
220 !13 = !DILocalVariable(name: "a
", scope: !9, file: !1, line: 1, type: !14)
221 !14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
222 !16 = !DILocation(line: 1, column: 21, scope: !9)
225 bool BrokenDebugInfo
= true;
226 verifyModule(*M
, &errs(), &BrokenDebugInfo
);
227 ASSERT_FALSE(BrokenDebugInfo
);
229 // Get the dbg.declare.
230 Function
&F
= *cast
<Function
>(M
->getNamedValue("fun"));
231 DbgVariableIntrinsic
*DbgDeclare
=
232 cast
<DbgVariableIntrinsic
>(&F
.front().front());
233 // Check that this form counts as a "no location" marker.
234 EXPECT_TRUE(DbgDeclare
->isKillLocation());
237 // Duplicate of above test, but in DPValue representation.
238 TEST(MetadataTest
, DeleteInstUsedByDPValue
) {
240 std::unique_ptr
<Module
> M
= parseIR(C
, R
"(
241 define i16 @f(i16 %a) !dbg !6 {
242 %b = add i16 %a, 1, !dbg !11
243 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11
244 call void @llvm.dbg.value(metadata !DIArgList(i16 %a, i16 %b), metadata !9, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus)), !dbg !11
247 declare void @llvm.dbg.value(metadata, metadata, metadata) #0
248 attributes #0 = { nounwind readnone speculatable willreturn }
251 !llvm.module.flags = !{!5}
253 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify
", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
254 !1 = !DIFile(filename: "t
.ll
", directory: "/")
256 !5 = !{i32 2, !"Debug Info Version
", i32 3}
257 !6 = distinct !DISubprogram(name: "foo
", linkageName: "foo
", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
258 !7 = !DISubroutineType(types: !2)
260 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
261 !10 = !DIBasicType(name: "ty16
", size: 16, encoding: DW_ATE_unsigned)
262 !11 = !DILocation(line: 1, column: 1, scope: !6)
265 bool OldDbgValueMode
= UseNewDbgInfoFormat
;
266 UseNewDbgInfoFormat
= true;
267 Instruction
&I
= *M
->getFunction("f")->getEntryBlock().getFirstNonPHI();
268 M
->convertToNewDbgValues();
270 // Find the DPValues using %b.
271 SmallVector
<DbgValueInst
*, 2> DVIs
;
272 SmallVector
<DPValue
*, 2> DPVs
;
273 findDbgValues(DVIs
, &I
, &DPVs
);
274 ASSERT_EQ(DPVs
.size(), 2u);
276 // Delete %b. The DPValue should now point to undef.
278 EXPECT_EQ(DPVs
[0]->getNumVariableLocationOps(), 1u);
279 EXPECT_TRUE(isa
<UndefValue
>(DPVs
[0]->getVariableLocationOp(0)));
280 EXPECT_TRUE(DPVs
[0]->isKillLocation());
281 EXPECT_EQ(DPVs
[1]->getNumVariableLocationOps(), 2u);
282 EXPECT_TRUE(isa
<UndefValue
>(DPVs
[1]->getVariableLocationOp(1)));
283 EXPECT_TRUE(DPVs
[1]->isKillLocation());
284 UseNewDbgInfoFormat
= OldDbgValueMode
;
287 // Ensure that the order of dbg.value intrinsics returned by findDbgValues, and
288 // their corresponding DPValue representation, are consistent.
289 TEST(MetadataTest
, OrderingOfDPValues
) {
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
298 declare void @llvm.dbg.value(metadata, metadata, metadata) #0
299 attributes #0 = { nounwind readnone speculatable willreturn }
302 !llvm.module.flags = !{!5}
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: "/")
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)
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)
317 bool OldDbgValueMode
= UseNewDbgInfoFormat
;
318 UseNewDbgInfoFormat
= true;
319 Instruction
&I
= *M
->getFunction("f")->getEntryBlock().getFirstNonPHI();
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);
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");
335 // Now try again, but in DPValue form.
338 M
->convertToNewDbgValues();
339 findDbgValues(DVIs
, &I
, &DPVs
);
340 ASSERT_EQ(DVIs
.size(), 0u);
341 ASSERT_EQ(DPVs
.size(), 2u);
343 Var0
= DPVs
[0]->getVariable();
344 EXPECT_TRUE(Var0
->getName() == "bar");
345 Var1
= DPVs
[1]->getVariable();
346 EXPECT_TRUE(Var1
->getName() == "foo");
348 M
->convertFromNewDbgValues();
349 UseNewDbgInfoFormat
= OldDbgValueMode
;
352 TEST(DIBuiler
, CreateFile
) {
354 std::unique_ptr
<Module
> M(new Module("MyModule", Ctx
));
357 DIFile
*F
= DIB
.createFile("main.c", "/");
358 EXPECT_EQ(std::nullopt
, F
->getSource());
360 std::optional
<DIFile::ChecksumInfo
<StringRef
>> Checksum
;
361 std::optional
<StringRef
> Source
;
362 F
= DIB
.createFile("main.c", "/", Checksum
, Source
);
363 EXPECT_EQ(Source
, F
->getSource());
366 F
= DIB
.createFile("main.c", "/", Checksum
, Source
);
367 EXPECT_EQ(Source
, F
->getSource());
370 TEST(DIBuilder
, CreateFortranArrayTypeWithAttributes
) {
372 std::unique_ptr
<Module
> M(new Module("MyModule", Ctx
));
375 DISubrange
*Subrange
= DIB
.getOrCreateSubrange(1,1);
376 SmallVector
<Metadata
*, 4> Subranges
;
377 Subranges
.push_back(Subrange
);
378 DINodeArray Subscripts
= DIB
.getOrCreateArray(Subranges
);
380 auto getDIExpression
= [&DIB
](int offset
) {
381 SmallVector
<uint64_t, 4> ops
;
382 ops
.push_back(llvm::dwarf::DW_OP_push_object_address
);
383 DIExpression::appendOffset(ops
, offset
);
384 ops
.push_back(llvm::dwarf::DW_OP_deref
);
386 return DIB
.createExpression(ops
);
389 DIFile
*F
= DIB
.createFile("main.c", "/");
390 DICompileUnit
*CU
= DIB
.createCompileUnit(
391 dwarf::DW_LANG_C
, DIB
.createFile("main.c", "/"), "llvm-c", true, "", 0);
393 DIVariable
*DataLocation
=
394 DIB
.createTempGlobalVariableFwdDecl(CU
, "dl", "_dl", F
, 1, nullptr, true);
395 DIExpression
*Associated
= getDIExpression(1);
396 DIExpression
*Allocated
= getDIExpression(2);
397 DIExpression
*Rank
= DIB
.createConstantValueExpression(3);
399 DICompositeType
*ArrayType
= DIB
.createArrayType(0, 0, nullptr, Subscripts
,
400 DataLocation
, Associated
,
403 EXPECT_TRUE(isa_and_nonnull
<DICompositeType
>(ArrayType
));
404 EXPECT_EQ(ArrayType
->getRawDataLocation(), DataLocation
);
405 EXPECT_EQ(ArrayType
->getRawAssociated(), Associated
);
406 EXPECT_EQ(ArrayType
->getRawAllocated(), Allocated
);
407 EXPECT_EQ(ArrayType
->getRawRank(), Rank
);
409 // Avoid memory leak.
410 DIVariable::deleteTemporary(DataLocation
);
413 TEST(DIBuilder
, CreateSetType
) {
415 std::unique_ptr
<Module
> M(new Module("MyModule", Ctx
));
417 DIScope
*Scope
= DISubprogram::getDistinct(
418 Ctx
, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0,
419 DINode::FlagZero
, DISubprogram::SPFlagZero
, nullptr);
420 DIType
*Type
= DIB
.createBasicType("Int", 64, dwarf::DW_ATE_signed
);
421 DIFile
*F
= DIB
.createFile("main.c", "/");
423 DIDerivedType
*SetType
= DIB
.createSetType(Scope
, "set1", F
, 1, 64, 64, Type
);
424 EXPECT_TRUE(isa_and_nonnull
<DIDerivedType
>(SetType
));
427 TEST(DIBuilder
, CreateStringType
) {
429 std::unique_ptr
<Module
> M(new Module("MyModule", Ctx
));
431 DIScope
*Scope
= DISubprogram::getDistinct(
432 Ctx
, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0,
433 DINode::FlagZero
, DISubprogram::SPFlagZero
, nullptr);
434 DIFile
*F
= DIB
.createFile("main.c", "/");
435 StringRef StrName
= "string";
436 DIVariable
*StringLen
= DIB
.createAutoVariable(Scope
, StrName
, F
, 0, nullptr,
437 false, DINode::FlagZero
, 0);
438 auto getDIExpression
= [&DIB
](int offset
) {
439 SmallVector
<uint64_t, 4> ops
;
440 ops
.push_back(llvm::dwarf::DW_OP_push_object_address
);
441 DIExpression::appendOffset(ops
, offset
);
442 ops
.push_back(llvm::dwarf::DW_OP_deref
);
444 return DIB
.createExpression(ops
);
446 DIExpression
*StringLocationExp
= getDIExpression(1);
447 DIStringType
*StringType
=
448 DIB
.createStringType(StrName
, StringLen
, StringLocationExp
);
450 EXPECT_TRUE(isa_and_nonnull
<DIStringType
>(StringType
));
451 EXPECT_EQ(StringType
->getName(), StrName
);
452 EXPECT_EQ(StringType
->getStringLength(), StringLen
);
453 EXPECT_EQ(StringType
->getStringLocationExp(), StringLocationExp
);
455 StringRef StrNameExp
= "stringexp";
456 DIExpression
*StringLengthExp
= getDIExpression(2);
457 DIStringType
*StringTypeExp
=
458 DIB
.createStringType(StrNameExp
, StringLengthExp
, StringLocationExp
);
460 EXPECT_TRUE(isa_and_nonnull
<DIStringType
>(StringTypeExp
));
461 EXPECT_EQ(StringTypeExp
->getName(), StrNameExp
);
462 EXPECT_EQ(StringTypeExp
->getStringLocationExp(), StringLocationExp
);
463 EXPECT_EQ(StringTypeExp
->getStringLengthExp(), StringLengthExp
);
466 TEST(DIBuilder
, DIEnumerator
) {
468 std::unique_ptr
<Module
> M(new Module("MyModule", Ctx
));
470 APSInt
I1(APInt(32, 1));
471 APSInt
I2(APInt(33, 1));
473 auto *E
= DIEnumerator::get(Ctx
, I1
, I1
.isSigned(), "name");
476 auto *E1
= DIEnumerator::getIfExists(Ctx
, I1
, I1
.isSigned(), "name");
479 auto *E2
= DIEnumerator::getIfExists(Ctx
, I2
, I1
.isSigned(), "name");
483 TEST(DbgAssignIntrinsicTest
, replaceVariableLocationOp
) {
485 std::unique_ptr
<Module
> M
= parseIR(C
, R
"(
486 define dso_local void @fun(i32 %v1, ptr %p1, ptr %p2) !dbg !7 {
488 call void @llvm.dbg.assign(metadata i32 %v1, metadata !14, metadata !DIExpression(), metadata !17, metadata ptr %p1, metadata !DIExpression()), !dbg !16
492 declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
495 !llvm.module.flags = !{!3}
497 !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version
14.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
498 !1 = !DIFile(filename: "test
.cpp
", directory: "/")
499 !3 = !{i32 2, !"Debug Info Version
", i32 3}
500 !7 = distinct !DISubprogram(name: "fun
", linkageName: "fun
", scope: !1, file: !1, line: 2, type: !8, scopeLine: 2, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
501 !8 = !DISubroutineType(types: !9)
503 !10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
505 !14 = !DILocalVariable(name: "Local
", scope: !7, file: !1, line: 3, type: !10)
506 !16 = !DILocation(line: 0, scope: !7)
507 !17 = distinct !DIAssignID()
509 // Check the test IR isn't malformed.
512 Function
&Fun
= *M
->getFunction("fun");
513 Value
*V1
= Fun
.getArg(0);
514 Value
*P1
= Fun
.getArg(1);
515 Value
*P2
= Fun
.getArg(2);
516 DbgAssignIntrinsic
*DAI
= cast
<DbgAssignIntrinsic
>(Fun
.begin()->begin());
517 ASSERT_TRUE(V1
== DAI
->getVariableLocationOp(0));
518 ASSERT_TRUE(P1
== DAI
->getAddress());
520 #define TEST_REPLACE(Old, New, ExpectedValue, ExpectedAddr) \
521 DAI->replaceVariableLocationOp(Old, New); \
522 EXPECT_EQ(DAI->getVariableLocationOp(0), ExpectedValue); \
523 EXPECT_EQ(DAI->getAddress(), ExpectedAddr);
525 // Replace address only.
526 TEST_REPLACE(/*Old*/ P1
, /*New*/ P2
, /*Value*/ V1
, /*Address*/ P2
);
527 // Replace value only.
528 TEST_REPLACE(/*Old*/ V1
, /*New*/ P2
, /*Value*/ P2
, /*Address*/ P2
);
530 TEST_REPLACE(/*Old*/ P2
, /*New*/ P1
, /*Value*/ P1
, /*Address*/ P1
);
532 // Replace address only, value uses a DIArgList.
533 // Value = {DIArgList(V1)}, Addr = P1.
534 DAI
->setRawLocation(DIArgList::get(C
, ValueAsMetadata::get(V1
)));
535 DAI
->setExpression(DIExpression::get(
536 C
, {dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_stack_value
}));
537 TEST_REPLACE(/*Old*/ P1
, /*New*/ P2
, /*Value*/ V1
, /*Address*/ P2
);
541 TEST(AssignmentTrackingTest
, Utils
) {
542 // Test the assignment tracking utils defined in DebugInfo.h namespace at {}.
544 // getAssignmentInsts
545 // getAssignmentMarkers
549 // The input IR includes two functions, fun1 and fun2. Both contain an alloca
550 // with a DIAssignID tag. fun1's alloca is linked to two llvm.dbg.assign
551 // intrinsics, one of which is for an inlined variable and appears before the
555 std::unique_ptr
<Module
> M
= parseIR(C
, R
"(
556 define dso_local void @fun1() !dbg !7 {
558 call void @llvm.dbg.assign(metadata i32 undef, metadata !10, metadata !DIExpression(), metadata !12, metadata i32 undef, metadata !DIExpression()), !dbg !13
559 %local = alloca i32, align 4, !DIAssignID !12
560 call void @llvm.dbg.assign(metadata i32 undef, metadata !16, metadata !DIExpression(), metadata !12, metadata i32 undef, metadata !DIExpression()), !dbg !15
564 define dso_local void @fun2() !dbg !17 {
566 %local = alloca i32, align 4, !DIAssignID !20
567 call void @llvm.dbg.assign(metadata i32 undef, metadata !18, metadata !DIExpression(), metadata !20, metadata i32 undef, metadata !DIExpression()), !dbg !19
571 define dso_local void @fun3() !dbg !21 {
573 %local = alloca i32, align 4, !DIAssignID !24
574 call void @llvm.dbg.assign(metadata i32 undef, metadata !22, metadata !DIExpression(), metadata !24, metadata i32* undef, metadata !DIExpression()), !dbg !23
578 declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
581 !llvm.module.flags = !{!3, !4, !5}
584 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version
14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
585 !1 = !DIFile(filename: "test
.c
", directory: "/")
587 !3 = !{i32 7, !"Dwarf Version
", i32 4}
588 !4 = !{i32 2, !"Debug Info Version
", i32 3}
589 !5 = !{i32 1, !"wchar_size
", i32 4}
590 !6 = !{!"clang version
14.0.0"}
591 !7 = distinct !DISubprogram(name: "fun1
", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
592 !8 = !DISubroutineType(types: !9)
594 !10 = !DILocalVariable(name: "local3
", scope: !14, file: !1, line: 2, type: !11)
595 !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
596 !12 = distinct !DIAssignID()
597 !13 = !DILocation(line: 5, column: 1, scope: !14, inlinedAt: !15)
598 !14 = distinct !DISubprogram(name: "inline", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
599 !15 = !DILocation(line: 3, column: 1, scope: !7)
600 !16 = !DILocalVariable(name: "local1
", scope: !7, file: !1, line: 2, type: !11)
601 !17 = distinct !DISubprogram(name: "fun2
", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
602 !18 = !DILocalVariable(name: "local2
", scope: !17, file: !1, line: 2, type: !11)
603 !19 = !DILocation(line: 4, column: 1, scope: !17)
604 !20 = distinct !DIAssignID()
605 !21 = distinct !DISubprogram(name: "fun3
", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
606 !22 = !DILocalVariable(name: "local4
", scope: !21, file: !1, line: 2, type: !11)
607 !23 = !DILocation(line: 4, column: 1, scope: !21)
608 !24 = distinct !DIAssignID()
611 // Check the test IR isn't malformed.
614 Function
&Fun1
= *M
->getFunction("fun1");
615 Instruction
&Alloca
= *Fun1
.getEntryBlock().getFirstNonPHIOrDbg();
617 // 1. Check the Instruction <-> Intrinsic mappings work in fun1.
619 // Check there are two llvm.dbg.assign intrinsics linked to Alloca.
620 auto CheckFun1Mapping
= [&Alloca
]() {
621 auto Markers
= at::getAssignmentMarkers(&Alloca
);
622 EXPECT_TRUE(std::distance(Markers
.begin(), Markers
.end()) == 2);
623 // Check those two entries are distinct.
624 DbgAssignIntrinsic
*First
= *Markers
.begin();
625 DbgAssignIntrinsic
*Second
= *std::next(Markers
.begin());
626 EXPECT_NE(First
, Second
);
628 // Check that we can get back to Alloca from each llvm.dbg.assign.
629 for (auto *DAI
: Markers
) {
630 auto Insts
= at::getAssignmentInsts(DAI
);
631 // Check there is exactly one instruction linked to each intrinsic. Use
632 // ASSERT_TRUE because we're going to dereference the begin iterator.
633 ASSERT_TRUE(std::distance(Insts
.begin(), Insts
.end()) == 1);
634 EXPECT_FALSE(Insts
.empty());
635 // Check the linked instruction is Alloca.
636 Instruction
*LinkedInst
= *Insts
.begin();
637 EXPECT_EQ(LinkedInst
, &Alloca
);
642 // 2. Check DIAssignID RAUW replaces attachments and uses.
645 cast_or_null
<DIAssignID
>(Alloca
.getMetadata(LLVMContext::MD_DIAssignID
));
646 DIAssignID
*New
= DIAssignID::getDistinct(C
);
647 ASSERT_TRUE(Old
&& New
&& New
!= Old
);
649 // Check fun1's alloca and intrinsics have been updated and the mapping still
651 EXPECT_EQ(New
, cast_or_null
<DIAssignID
>(
652 Alloca
.getMetadata(LLVMContext::MD_DIAssignID
)));
655 // Check that fun2's alloca and intrinsic have not not been updated.
656 Instruction
&Fun2Alloca
=
657 *M
->getFunction("fun2")->getEntryBlock().getFirstNonPHIOrDbg();
658 DIAssignID
*Fun2ID
= cast_or_null
<DIAssignID
>(
659 Fun2Alloca
.getMetadata(LLVMContext::MD_DIAssignID
));
660 EXPECT_NE(New
, Fun2ID
);
661 auto Fun2Markers
= at::getAssignmentMarkers(&Fun2Alloca
);
662 ASSERT_TRUE(std::distance(Fun2Markers
.begin(), Fun2Markers
.end()) == 1);
663 auto Fun2Insts
= at::getAssignmentInsts(*Fun2Markers
.begin());
664 ASSERT_TRUE(std::distance(Fun2Insts
.begin(), Fun2Insts
.end()) == 1);
665 EXPECT_EQ(*Fun2Insts
.begin(), &Fun2Alloca
);
667 // 3. Check that deleting dbg.assigns from a specific instruction works.
668 Instruction
&Fun3Alloca
=
669 *M
->getFunction("fun3")->getEntryBlock().getFirstNonPHIOrDbg();
670 auto Fun3Markers
= at::getAssignmentMarkers(&Fun3Alloca
);
671 ASSERT_TRUE(std::distance(Fun3Markers
.begin(), Fun3Markers
.end()) == 1);
672 at::deleteAssignmentMarkers(&Fun3Alloca
);
673 Fun3Markers
= at::getAssignmentMarkers(&Fun3Alloca
);
674 EXPECT_EQ(Fun3Markers
.empty(), true);
676 // 4. Check that deleting works and applies only to the target function.
677 at::deleteAll(&Fun1
);
678 // There should now only be the alloca and ret in fun1.
679 EXPECT_EQ(Fun1
.begin()->size(), 2u);
680 // fun2's alloca should have the same DIAssignID and remain linked to its
682 EXPECT_EQ(Fun2ID
, cast_or_null
<DIAssignID
>(
683 Fun2Alloca
.getMetadata(LLVMContext::MD_DIAssignID
)));
684 EXPECT_FALSE(at::getAssignmentMarkers(&Fun2Alloca
).empty());
687 TEST(IRBuilder
, GetSetInsertionPointWithEmptyBasicBlock
) {
689 std::unique_ptr
<BasicBlock
> BB(BasicBlock::Create(C
, "start"));
690 Module
*M
= new Module("module", C
);
691 IRBuilder
<> Builder(BB
.get());
692 Function
*DbgDeclare
= Intrinsic::getDeclaration(M
, Intrinsic::dbg_declare
);
693 Value
*DIV
= MetadataAsValue::get(C
, (Metadata
*)nullptr);
694 SmallVector
<Value
*, 3> Args
= {DIV
, DIV
, DIV
};
695 Builder
.CreateCall(DbgDeclare
, Args
);
696 auto IP
= BB
->getFirstInsertionPt();
697 Builder
.SetInsertPoint(BB
.get(), IP
);
700 TEST(AssignmentTrackingTest
, InstrMethods
) {
701 // Test the assignment tracking Instruction methods.
703 // Instruction::mergeDIAssignID
706 std::unique_ptr
<Module
> M
= parseIR(C
, R
"(
707 define dso_local void @fun() #0 !dbg !8 {
709 %Local = alloca [2 x i32], align 4, !DIAssignID !12
710 call void @llvm.dbg.assign(metadata i1 undef, metadata !13, metadata !DIExpression(), metadata !12, metadata [2 x i32]* %Local, metadata !DIExpression()), !dbg !18
711 %arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* %Local, i64 0, i64 0, !dbg !19
712 store i32 5, i32* %arrayidx, align 4, !dbg !20, !DIAssignID !21
713 call void @llvm.dbg.assign(metadata i32 5, metadata !13, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32), metadata !21, metadata i32* %arrayidx, metadata !DIExpression()), !dbg !18
714 %arrayidx1 = getelementptr inbounds [2 x i32], [2 x i32]* %Local, i64 0, i64 1, !dbg !22
715 store i32 6, i32* %arrayidx1, align 4, !dbg !23, !DIAssignID !24
716 call void @llvm.dbg.assign(metadata i32 6, metadata !13, metadata !DIExpression(DW_OP_LLVM_fragment, 32, 32), metadata !24, metadata i32* %arrayidx1, metadata !DIExpression()), !dbg !18
720 declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata) #1
723 !llvm.module.flags = !{!2, !3, !4, !5, !6}
726 !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version
14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
727 !1 = !DIFile(filename: "test
.cpp
", directory: "/")
728 !2 = !{i32 7, !"Dwarf Version
", i32 5}
729 !3 = !{i32 2, !"Debug Info Version
", i32 3}
730 !4 = !{i32 1, !"wchar_size
", i32 4}
731 !5 = !{i32 7, !"uwtable
", i32 1}
732 !6 = !{i32 7, !"frame
-pointer
", i32 2}
733 !7 = !{!"clang version
14.0.0"}
734 !8 = distinct !DISubprogram(name: "fun
", linkageName: "fun
", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !11)
735 !9 = !DISubroutineType(types: !10)
738 !12 = distinct !DIAssignID()
739 !13 = !DILocalVariable(name: "Local
", scope: !8, file: !1, line: 2, type: !14)
740 !14 = !DICompositeType(tag: DW_TAG_array_type, baseType: !15, size: 64, elements: !16)
741 !15 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
743 !17 = !DISubrange(count: 2)
744 !18 = !DILocation(line: 0, scope: !8)
745 !19 = !DILocation(line: 3, column: 3, scope: !8)
746 !20 = !DILocation(line: 3, column: 12, scope: !8)
747 !21 = distinct !DIAssignID()
748 !22 = !DILocation(line: 4, column: 3, scope: !8)
749 !23 = !DILocation(line: 4, column: 12, scope: !8)
750 !24 = distinct !DIAssignID()
751 !25 = !DILocation(line: 5, column: 1, scope: !8)
754 // Check the test IR isn't malformed.
756 Function
&Fun
= *M
->getFunction("fun");
757 SmallVector
<Instruction
*> Stores
;
758 for (auto &BB
: Fun
) {
760 if (isa
<StoreInst
>(&I
))
761 Stores
.push_back(&I
);
765 // The test requires (at least) 2 stores.
766 ASSERT_TRUE(Stores
.size() == 2);
767 // Use SetVectors to check that the attachments and markers are unique
768 // (another test requirement).
769 SetVector
<Metadata
*> OrigIDs
;
770 SetVector
<DbgAssignIntrinsic
*> Markers
;
771 for (const Instruction
*SI
: Stores
) {
772 Metadata
*ID
= SI
->getMetadata(LLVMContext::MD_DIAssignID
);
773 ASSERT_TRUE(OrigIDs
.insert(ID
));
774 ASSERT_TRUE(ID
!= nullptr);
775 auto Range
= at::getAssignmentMarkers(SI
);
776 ASSERT_TRUE(std::distance(Range
.begin(), Range
.end()) == 1);
777 ASSERT_TRUE(Markers
.insert(*Range
.begin()));
780 // Test 1 - mergeDIAssignID.
782 // Input store0->mergeDIAssignID(store1)
783 // ----- -------------------------
784 // store0 !x store0 !x
785 // dbg.assign0 !x dbg.assign !x
786 // store1 !y store1 !x
787 // dbg.assign1 !y dbg.assign1 !x
789 Stores
[0]->mergeDIAssignID(Stores
[1]);
790 // Check that the stores share the same ID.
791 Metadata
*NewID0
= Stores
[0]->getMetadata(LLVMContext::MD_DIAssignID
);
792 Metadata
*NewID1
= Stores
[1]->getMetadata(LLVMContext::MD_DIAssignID
);
793 EXPECT_NE(NewID0
, nullptr);
794 EXPECT_EQ(NewID0
, NewID1
);
795 EXPECT_EQ(Markers
[0]->getAssignID(), NewID0
);
796 EXPECT_EQ(Markers
[1]->getAssignID(), NewID0
);
799 // Test 2 - mergeDIAssignID.
801 // Input store0->mergeDIAssignID(store1)
802 // ----- -------------------------
803 // store0 !x store0 !x
804 // dbg.assign0 !x dbg.assign !x
807 Stores
[1]->setMetadata(LLVMContext::MD_DIAssignID
, nullptr);
808 Stores
[0]->mergeDIAssignID(Stores
[1]);
809 // Check that store1 doesn't get a new ID.
810 Metadata
*NewID0
= Stores
[0]->getMetadata(LLVMContext::MD_DIAssignID
);
811 Metadata
*NewID1
= Stores
[1]->getMetadata(LLVMContext::MD_DIAssignID
);
812 EXPECT_NE(NewID0
, nullptr);
813 EXPECT_EQ(NewID1
, nullptr);
814 EXPECT_EQ(Markers
[0]->getAssignID(), NewID0
);
817 // Test 3 - mergeDIAssignID.
819 // Input store1->mergeDIAssignID(store0)
820 // ----- -------------------------
821 // store0 !x store0 !x
822 // dbg.assign0 !x dbg.assign !x
825 Stores
[1]->setMetadata(LLVMContext::MD_DIAssignID
, nullptr);
826 Stores
[1]->mergeDIAssignID(Stores
[0]);
827 // Check that the stores share the same ID (note store1 starts with none).
828 Metadata
*NewID0
= Stores
[0]->getMetadata(LLVMContext::MD_DIAssignID
);
829 Metadata
*NewID1
= Stores
[1]->getMetadata(LLVMContext::MD_DIAssignID
);
830 EXPECT_NE(NewID0
, nullptr);
831 EXPECT_EQ(NewID0
, NewID1
);
832 EXPECT_EQ(Markers
[0]->getAssignID(), NewID0
);
835 // Test 4 - mergeDIAssignID.
837 // Input store1->mergeDIAssignID(store0)
838 // ----- -------------------------
839 // store0 !x store0 !x
840 // dbg.assign0 !x dbg.assign !x
841 // store1 !x store1 !x
843 Stores
[0]->mergeDIAssignID(Stores
[1]);
844 // Check that the stores share the same ID.
845 Metadata
*NewID0
= Stores
[0]->getMetadata(LLVMContext::MD_DIAssignID
);
846 Metadata
*NewID1
= Stores
[1]->getMetadata(LLVMContext::MD_DIAssignID
);
847 EXPECT_NE(NewID0
, nullptr);
848 EXPECT_EQ(NewID0
, NewID1
);
849 EXPECT_EQ(Markers
[0]->getAssignID(), NewID0
);
852 // Test 5 - dropUnknownNonDebugMetadata.
854 // Input store0->dropUnknownNonDebugMetadata()
855 // ----- -------------------------
856 // store0 !x store0 !x
858 Stores
[0]->dropUnknownNonDebugMetadata();
859 Metadata
*NewID0
= Stores
[0]->getMetadata(LLVMContext::MD_DIAssignID
);
860 EXPECT_NE(NewID0
, nullptr);
864 // Test some very straight-forward operations on DPValues -- these are
865 // dbg.values that have been converted to a non-instruction format.
866 TEST(MetadataTest
, ConvertDbgToDPValue
) {
868 std::unique_ptr
<Module
> M
= parseIR(C
, R
"(
869 define i16 @f(i16 %a) !dbg !6 {
870 call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11
871 %b = add i16 %a, 1, !dbg !11
872 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11
876 %c = add i16 %b, 1, !dbg !11
879 declare void @llvm.dbg.value(metadata, metadata, metadata) #0
880 attributes #0 = { nounwind readnone speculatable willreturn }
883 !llvm.module.flags = !{!5}
885 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify
", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
886 !1 = !DIFile(filename: "t
.ll
", directory: "/")
888 !5 = !{i32 2, !"Debug Info Version
", i32 3}
889 !6 = distinct !DISubprogram(name: "foo
", linkageName: "foo
", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
890 !7 = !DISubroutineType(types: !2)
892 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
893 !10 = !DIBasicType(name: "ty16
", size: 16, encoding: DW_ATE_unsigned)
894 !11 = !DILocation(line: 1, column: 1, scope: !6)
897 // Find the first dbg.value,
898 Instruction
&I
= *M
->getFunction("f")->getEntryBlock().getFirstNonPHI();
899 const DILocalVariable
*Var
= nullptr;
900 const DIExpression
*Expr
= nullptr;
901 const DILocation
*Loc
= nullptr;
902 const Metadata
*MLoc
= nullptr;
903 DPValue
*DPV1
= nullptr;
905 DbgValueInst
*DPI
= dyn_cast
<DbgValueInst
>(&I
);
907 Var
= DPI
->getVariable();
908 Expr
= DPI
->getExpression();
909 Loc
= DPI
->getDebugLoc().get();
910 MLoc
= DPI
->getRawLocation();
912 // Test the creation of a DPValue and it's conversion back to a dbg.value.
913 DPV1
= new DPValue(DPI
);
914 EXPECT_EQ(DPV1
->getVariable(), Var
);
915 EXPECT_EQ(DPV1
->getExpression(), Expr
);
916 EXPECT_EQ(DPV1
->getDebugLoc().get(), Loc
);
917 EXPECT_EQ(DPV1
->getRawLocation(), MLoc
);
920 DPI
->eraseFromParent();
921 // Re-create from DPV1, inserting at front.
922 DPV1
->createDebugIntrinsic(&*M
,
923 &M
->getFunction("f")->getEntryBlock().front());
925 Instruction
*NewDPI
= &M
->getFunction("f")->getEntryBlock().front();
926 DbgValueInst
*DPI2
= dyn_cast
<DbgValueInst
>(NewDPI
);
928 EXPECT_EQ(DPI2
->getVariable(), Var
);
929 EXPECT_EQ(DPI2
->getExpression(), Expr
);
930 EXPECT_EQ(DPI2
->getDebugLoc().get(), Loc
);
931 EXPECT_EQ(DPI2
->getRawLocation(), MLoc
);
934 // Fetch the second dbg.value, convert it to a DPValue,
935 BasicBlock::iterator It
= M
->getFunction("f")->getEntryBlock().begin();
936 It
= std::next(std::next(It
));
937 DbgValueInst
*DPI3
= dyn_cast
<DbgValueInst
>(It
);
939 DPValue
*DPV2
= new DPValue(DPI3
);
941 // These dbg.values are supposed to refer to different values.
942 EXPECT_NE(DPV1
->getRawLocation(), DPV2
->getRawLocation());
944 // Try manipulating DPValues and markers in the exit block.
945 BasicBlock
*ExitBlock
= &*std::next(M
->getFunction("f")->getEntryBlock().getIterator());
946 Instruction
*FirstInst
= &ExitBlock
->front();
947 Instruction
*RetInst
= &*std::next(FirstInst
->getIterator());
949 // Set-up DPMarkers in this block.
950 ExitBlock
->IsNewDbgInfoFormat
= true;
951 ExitBlock
->createMarker(FirstInst
);
952 ExitBlock
->createMarker(RetInst
);
954 // Insert DPValues into markers, order should come out DPV2, DPV1.
955 FirstInst
->DbgMarker
->insertDPValue(DPV1
, false);
956 FirstInst
->DbgMarker
->insertDPValue(DPV2
, true);
957 unsigned int ItCount
= 0;
958 for (DPValue
&Item
: FirstInst
->DbgMarker
->getDbgValueRange()) {
959 EXPECT_TRUE((&Item
== DPV2
&& ItCount
== 0) ||
960 (&Item
== DPV1
&& ItCount
== 1));
961 EXPECT_EQ(Item
.getMarker(), FirstInst
->DbgMarker
);
965 // Clone them onto the second marker -- should allocate new DPVs.
966 RetInst
->DbgMarker
->cloneDebugInfoFrom(FirstInst
->DbgMarker
, std::nullopt
, false);
967 EXPECT_EQ(RetInst
->DbgMarker
->StoredDPValues
.size(), 2u);
969 // Check these things store the same information; but that they're not the same
971 for (DPValue
&Item
: RetInst
->DbgMarker
->getDbgValueRange()) {
972 EXPECT_TRUE((Item
.getRawLocation() == DPV2
->getRawLocation() && ItCount
== 0) ||
973 (Item
.getRawLocation() == DPV1
->getRawLocation() && ItCount
== 1));
975 EXPECT_EQ(Item
.getMarker(), RetInst
->DbgMarker
);
976 EXPECT_NE(&Item
, DPV1
);
977 EXPECT_NE(&Item
, DPV2
);
981 RetInst
->DbgMarker
->dropDPValues();
982 EXPECT_EQ(RetInst
->DbgMarker
->StoredDPValues
.size(), 0u);
984 // Try cloning one single DPValue.
985 auto DIIt
= std::next(FirstInst
->DbgMarker
->getDbgValueRange().begin());
986 RetInst
->DbgMarker
->cloneDebugInfoFrom(FirstInst
->DbgMarker
, DIIt
, false);
987 EXPECT_EQ(RetInst
->DbgMarker
->StoredDPValues
.size(), 1u);
988 // The second DPValue should have been cloned; it should have the same values
990 EXPECT_EQ(RetInst
->DbgMarker
->StoredDPValues
.begin()->getRawLocation(),
991 DPV1
->getRawLocation());
992 // We should be able to drop individual DPValues.
993 RetInst
->DbgMarker
->dropOneDPValue(&*RetInst
->DbgMarker
->StoredDPValues
.begin());
995 // "Aborb" a DPMarker: this means pretend that the instruction it's attached
996 // to is disappearing so it needs to be transferred into "this" marker.
997 RetInst
->DbgMarker
->absorbDebugValues(*FirstInst
->DbgMarker
, true);
998 EXPECT_EQ(RetInst
->DbgMarker
->StoredDPValues
.size(), 2u);
999 // Should be the DPV1 and DPV2 objects.
1001 for (DPValue
&Item
: RetInst
->DbgMarker
->getDbgValueRange()) {
1002 EXPECT_TRUE((&Item
== DPV2
&& ItCount
== 0) ||
1003 (&Item
== DPV1
&& ItCount
== 1));
1004 EXPECT_EQ(Item
.getMarker(), RetInst
->DbgMarker
);
1008 // Finally -- there are two DPValues left over. If we remove evrything in the
1009 // basic block, then they should sink down into the "TrailingDPValues"
1010 // container for dangling debug-info. Future facilities will restore them
1011 // back when a terminator is inserted.
1012 FirstInst
->DbgMarker
->removeMarker();
1013 FirstInst
->eraseFromParent();
1014 RetInst
->DbgMarker
->removeMarker();
1015 RetInst
->eraseFromParent();
1017 DPMarker
*EndMarker
= ExitBlock
->getTrailingDPValues();
1018 ASSERT_NE(EndMarker
, nullptr);
1019 EXPECT_EQ(EndMarker
->StoredDPValues
.size(), 2u);
1020 // Test again that it's those two DPValues, DPV1 and DPV2.
1022 for (DPValue
&Item
: EndMarker
->getDbgValueRange()) {
1023 EXPECT_TRUE((&Item
== DPV2
&& ItCount
== 0) ||
1024 (&Item
== DPV1
&& ItCount
== 1));
1025 EXPECT_EQ(Item
.getMarker(), EndMarker
);
1029 // Cleanup the trailing DPValue records and marker.
1030 EndMarker
->eraseFromParent();
1032 // The record of those trailing DPValues would dangle and cause an assertion
1033 // failure if it lived until the end of the LLVMContext.
1034 ExitBlock
->deleteTrailingDPValues();
1037 TEST(MetadataTest
, DPValueConversionRoutines
) {
1040 // For the purpose of this test, set and un-set the command line option
1041 // corresponding to UseNewDbgInfoFormat.
1042 UseNewDbgInfoFormat
= true;
1044 std::unique_ptr
<Module
> M
= parseIR(C
, R
"(
1045 define i16 @f(i16 %a) !dbg !6 {
1046 call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11
1047 %b = add i16 %a, 1, !dbg !11
1048 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11
1052 %c = add i16 %b, 1, !dbg !11
1055 declare void @llvm.dbg.value(metadata, metadata, metadata) #0
1056 attributes #0 = { nounwind readnone speculatable willreturn }
1058 !llvm.dbg.cu = !{!0}
1059 !llvm.module.flags = !{!5}
1061 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify
", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
1062 !1 = !DIFile(filename: "t
.ll
", directory: "/")
1064 !5 = !{i32 2, !"Debug Info Version
", i32 3}
1065 !6 = distinct !DISubprogram(name: "foo
", linkageName: "foo
", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
1066 !7 = !DISubroutineType(types: !2)
1068 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
1069 !10 = !DIBasicType(name: "ty16
", size: 16, encoding: DW_ATE_unsigned)
1070 !11 = !DILocation(line: 1, column: 1, scope: !6)
1073 // Check that the conversion routines and utilities between dbg.value
1074 // debug-info format and DPValues works.
1075 Function
*F
= M
->getFunction("f");
1076 BasicBlock
*BB1
= &F
->getEntryBlock();
1077 // First instruction should be a dbg.value.
1078 EXPECT_TRUE(isa
<DbgValueInst
>(BB1
->front()));
1079 EXPECT_FALSE(BB1
->IsNewDbgInfoFormat
);
1080 // Validating the block for DPValues / DPMarkers shouldn't fail -- there's
1081 // no data stored right now.
1082 EXPECT_FALSE(BB1
->validateDbgValues(false, false));
1084 // Function and module should be marked as not having the new format too.
1085 EXPECT_FALSE(F
->IsNewDbgInfoFormat
);
1086 EXPECT_FALSE(M
->IsNewDbgInfoFormat
);
1089 M
->convertToNewDbgValues();
1090 EXPECT_TRUE(M
->IsNewDbgInfoFormat
);
1091 EXPECT_TRUE(F
->IsNewDbgInfoFormat
);
1092 EXPECT_TRUE(BB1
->IsNewDbgInfoFormat
);
1094 // There should now be no dbg.value instructions!
1095 // Ensure the first instruction exists, the test all of them.
1096 EXPECT_FALSE(isa
<DbgValueInst
>(BB1
->front()));
1099 EXPECT_FALSE(isa
<DbgValueInst
>(I
));
1101 // There should be a DPMarker on each of the two instructions in the entry
1102 // block, each containing one DPValue.
1103 EXPECT_EQ(BB1
->size(), 2u);
1104 Instruction
*FirstInst
= &BB1
->front();
1105 Instruction
*SecondInst
= FirstInst
->getNextNode();
1106 ASSERT_TRUE(FirstInst
->DbgMarker
);
1107 ASSERT_TRUE(SecondInst
->DbgMarker
);
1108 EXPECT_NE(FirstInst
->DbgMarker
, SecondInst
->DbgMarker
);
1109 EXPECT_EQ(FirstInst
, FirstInst
->DbgMarker
->MarkedInstr
);
1110 EXPECT_EQ(SecondInst
, SecondInst
->DbgMarker
->MarkedInstr
);
1112 EXPECT_EQ(FirstInst
->DbgMarker
->StoredDPValues
.size(), 1u);
1113 DPValue
*DPV1
= &*FirstInst
->DbgMarker
->getDbgValueRange().begin();
1114 EXPECT_EQ(DPV1
->getMarker(), FirstInst
->DbgMarker
);
1115 // Should point at %a, an argument.
1116 EXPECT_TRUE(isa
<Argument
>(DPV1
->getVariableLocationOp(0)));
1118 EXPECT_EQ(SecondInst
->DbgMarker
->StoredDPValues
.size(), 1u);
1119 DPValue
*DPV2
= &*SecondInst
->DbgMarker
->getDbgValueRange().begin();
1120 EXPECT_EQ(DPV2
->getMarker(), SecondInst
->DbgMarker
);
1121 // Should point at FirstInst.
1122 EXPECT_EQ(DPV2
->getVariableLocationOp(0), FirstInst
);
1124 // There should be no DPValues / DPMarkers in the second block, but it should
1125 // be marked as being in the new format.
1126 BasicBlock
*BB2
= BB1
->getNextNode();
1127 EXPECT_TRUE(BB2
->IsNewDbgInfoFormat
);
1128 for (auto &Inst
: *BB2
)
1129 // Either there should be no marker, or it should be empty.
1130 EXPECT_TRUE(!Inst
.DbgMarker
|| Inst
.DbgMarker
->StoredDPValues
.empty());
1132 // Validating the first block should continue to not be a problem,
1133 EXPECT_FALSE(BB1
->validateDbgValues(false, false));
1134 // But if we were to break something, it should be able to fire. Don't attempt
1135 // to comprehensively test the validator, it's a smoke-test rather than a
1136 // "proper" verification pass.
1137 DPV1
->setMarker(nullptr);
1138 // A marker pointing the wrong way should be an error.
1139 EXPECT_TRUE(BB1
->validateDbgValues(false, false));
1140 DPV1
->setMarker(FirstInst
->DbgMarker
);
1142 DILocalVariable
*DLV1
= DPV1
->getVariable();
1143 DIExpression
*Expr1
= DPV1
->getExpression();
1144 DILocalVariable
*DLV2
= DPV2
->getVariable();
1145 DIExpression
*Expr2
= DPV2
->getExpression();
1147 // Convert everything back to the "old" format and ensure it's right.
1148 M
->convertFromNewDbgValues();
1149 EXPECT_FALSE(M
->IsNewDbgInfoFormat
);
1150 EXPECT_FALSE(F
->IsNewDbgInfoFormat
);
1151 EXPECT_FALSE(BB1
->IsNewDbgInfoFormat
);
1153 EXPECT_EQ(BB1
->size(), 4u);
1154 ASSERT_TRUE(isa
<DbgValueInst
>(BB1
->front()));
1155 DbgValueInst
*DVI1
= cast
<DbgValueInst
>(&BB1
->front());
1156 // These dbg.values should still point at the same places.
1157 EXPECT_TRUE(isa
<Argument
>(DVI1
->getVariableLocationOp(0)));
1158 DbgValueInst
*DVI2
= cast
<DbgValueInst
>(DVI1
->getNextNode()->getNextNode());
1159 EXPECT_EQ(DVI2
->getVariableLocationOp(0), FirstInst
);
1161 // Check a few fields too,
1162 EXPECT_EQ(DVI1
->getVariable(), DLV1
);
1163 EXPECT_EQ(DVI1
->getExpression(), Expr1
);
1164 EXPECT_EQ(DVI2
->getVariable(), DLV2
);
1165 EXPECT_EQ(DVI2
->getExpression(), Expr2
);
1167 UseNewDbgInfoFormat
= false;