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 "../lib/IR/LLVMContextImpl.h"
11 #include "llvm/ADT/APSInt.h"
12 #include "llvm/AsmParser/Parser.h"
13 #include "llvm/IR/DIBuilder.h"
14 #include "llvm/IR/DebugInfoMetadata.h"
15 #include "llvm/IR/DebugProgramInstruction.h"
16 #include "llvm/IR/IRBuilder.h"
17 #include "llvm/IR/IntrinsicInst.h"
18 #include "llvm/IR/LLVMContext.h"
19 #include "llvm/IR/Metadata.h"
20 #include "llvm/IR/Module.h"
21 #include "llvm/IR/Verifier.h"
22 #include "llvm/Support/SourceMgr.h"
23 #include "llvm/Transforms/Utils/Local.h"
25 #include "gtest/gtest.h"
29 extern cl::opt
<bool> UseNewDbgInfoFormat
;
31 static std::unique_ptr
<Module
> parseIR(LLVMContext
&C
, const char *IR
) {
33 std::unique_ptr
<Module
> Mod
= parseAssemblyString(IR
, Err
, C
);
35 Err
.print("DebugInfoTest", errs());
41 TEST(DINodeTest
, getFlag
) {
43 EXPECT_EQ(DINode::FlagPublic
, DINode::getFlag("DIFlagPublic"));
44 EXPECT_EQ(DINode::FlagProtected
, DINode::getFlag("DIFlagProtected"));
45 EXPECT_EQ(DINode::FlagPrivate
, DINode::getFlag("DIFlagPrivate"));
46 EXPECT_EQ(DINode::FlagVector
, DINode::getFlag("DIFlagVector"));
47 EXPECT_EQ(DINode::FlagRValueReference
,
48 DINode::getFlag("DIFlagRValueReference"));
50 // FlagAccessibility shouldn't work.
51 EXPECT_EQ(0u, DINode::getFlag("DIFlagAccessibility"));
53 // Some other invalid strings.
54 EXPECT_EQ(0u, DINode::getFlag("FlagVector"));
55 EXPECT_EQ(0u, DINode::getFlag("Vector"));
56 EXPECT_EQ(0u, DINode::getFlag("other things"));
57 EXPECT_EQ(0u, DINode::getFlag("DIFlagOther"));
60 TEST(DINodeTest
, getFlagString
) {
62 EXPECT_EQ(StringRef("DIFlagPublic"),
63 DINode::getFlagString(DINode::FlagPublic
));
64 EXPECT_EQ(StringRef("DIFlagProtected"),
65 DINode::getFlagString(DINode::FlagProtected
));
66 EXPECT_EQ(StringRef("DIFlagPrivate"),
67 DINode::getFlagString(DINode::FlagPrivate
));
68 EXPECT_EQ(StringRef("DIFlagVector"),
69 DINode::getFlagString(DINode::FlagVector
));
70 EXPECT_EQ(StringRef("DIFlagRValueReference"),
71 DINode::getFlagString(DINode::FlagRValueReference
));
73 // FlagAccessibility actually equals FlagPublic.
74 EXPECT_EQ(StringRef("DIFlagPublic"),
75 DINode::getFlagString(DINode::FlagAccessibility
));
77 // Some other invalid flags.
78 EXPECT_EQ(StringRef(),
79 DINode::getFlagString(DINode::FlagPublic
| DINode::FlagVector
));
80 EXPECT_EQ(StringRef(), DINode::getFlagString(DINode::FlagFwdDecl
|
81 DINode::FlagArtificial
));
82 EXPECT_EQ(StringRef(),
83 DINode::getFlagString(static_cast<DINode::DIFlags
>(0xffff)));
86 TEST(DINodeTest
, splitFlags
) {
88 #define CHECK_SPLIT(FLAGS, VECTOR, REMAINDER) \
90 SmallVector<DINode::DIFlags, 8> V; \
91 EXPECT_EQ(REMAINDER, DINode::splitFlags(FLAGS, V)); \
92 EXPECT_TRUE(ArrayRef(V).equals(VECTOR)); \
94 CHECK_SPLIT(DINode::FlagPublic
, {DINode::FlagPublic
}, DINode::FlagZero
);
95 CHECK_SPLIT(DINode::FlagProtected
, {DINode::FlagProtected
}, DINode::FlagZero
);
96 CHECK_SPLIT(DINode::FlagPrivate
, {DINode::FlagPrivate
}, DINode::FlagZero
);
97 CHECK_SPLIT(DINode::FlagVector
, {DINode::FlagVector
}, DINode::FlagZero
);
98 CHECK_SPLIT(DINode::FlagRValueReference
, {DINode::FlagRValueReference
},
100 DINode::DIFlags Flags
[] = {DINode::FlagFwdDecl
, DINode::FlagVector
};
101 CHECK_SPLIT(DINode::FlagFwdDecl
| DINode::FlagVector
, Flags
,
103 CHECK_SPLIT(DINode::FlagZero
, {}, DINode::FlagZero
);
107 TEST(StripTest
, LoopMetadata
) {
109 std::unique_ptr
<Module
> M
= parseIR(C
, R
"(
110 define void @f() !dbg !5 {
111 ret void, !dbg !10, !llvm.loop !11
115 !llvm.debugify = !{!3, !3}
116 !llvm.module.flags = !{!4}
118 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify
", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
119 !1 = !DIFile(filename: "loop
.ll
", directory: "/")
122 !4 = !{i32 2, !"Debug Info Version
", i32 3}
123 !5 = distinct !DISubprogram(name: "f
", linkageName: "f
", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !7)
124 !6 = !DISubroutineType(types: !2)
126 !8 = !DILocalVariable(name: "1", scope: !5, file: !1, line: 1, type: !9)
127 !9 = !DIBasicType(name: "ty32
", size: 32, encoding: DW_ATE_unsigned)
128 !10 = !DILocation(line: 1, column: 1, scope: !5)
129 !11 = distinct !{!11, !10, !10}
132 // Look up the debug info emission kind for the CU via the loop metadata
133 // attached to the terminator. If, when stripping non-line table debug info,
134 // we update the terminator's metadata correctly, we should be able to
135 // observe the change in emission kind for the CU.
136 auto getEmissionKind
= [&]() {
137 Instruction
&I
= *M
->getFunction("f")->getEntryBlock().getFirstNonPHI();
138 MDNode
*LoopMD
= I
.getMetadata(LLVMContext::MD_loop
);
139 return cast
<DILocation
>(LoopMD
->getOperand(1))
146 EXPECT_EQ(getEmissionKind(), DICompileUnit::FullDebug
);
148 bool Changed
= stripNonLineTableDebugInfo(*M
);
149 EXPECT_TRUE(Changed
);
151 EXPECT_EQ(getEmissionKind(), DICompileUnit::LineTablesOnly
);
153 bool BrokenDebugInfo
= false;
154 bool HardError
= verifyModule(*M
, &errs(), &BrokenDebugInfo
);
155 EXPECT_FALSE(HardError
);
156 EXPECT_FALSE(BrokenDebugInfo
);
159 TEST(MetadataTest
, DeleteInstUsedByDbgRecord
) {
161 std::unique_ptr
<Module
> M
= parseIR(C
, R
"(
162 define i16 @f(i16 %a) !dbg !6 {
163 %b = add i16 %a, 1, !dbg !11
164 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11
167 declare void @llvm.dbg.value(metadata, metadata, metadata) #0
168 attributes #0 = { nounwind readnone speculatable willreturn }
171 !llvm.module.flags = !{!5}
173 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify
", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
174 !1 = !DIFile(filename: "t
.ll
", directory: "/")
176 !5 = !{i32 2, !"Debug Info Version
", i32 3}
177 !6 = distinct !DISubprogram(name: "foo
", linkageName: "foo
", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
178 !7 = !DISubroutineType(types: !2)
180 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
181 !10 = !DIBasicType(name: "ty16
", size: 16, encoding: DW_ATE_unsigned)
182 !11 = !DILocation(line: 1, column: 1, scope: !6)
186 Instruction
&I
= *M
->getFunction("f")->getEntryBlock().getFirstNonPHI();
188 // Find the dbg.value using %b.
189 SmallVector
<DbgValueInst
*, 1> DVIs
;
190 SmallVector
<DbgVariableRecord
*, 1> DVRs
;
191 findDbgValues(DVIs
, &I
, &DVRs
);
193 // Delete %b. The dbg.value should now point to undef.
195 EXPECT_EQ(DVRs
[0]->getNumVariableLocationOps(), 1u);
196 EXPECT_TRUE(isa
<UndefValue
>(DVRs
[0]->getValue(0)));
199 TEST(DbgVariableIntrinsic
, EmptyMDIsKillLocation
) {
201 std::unique_ptr
<Module
> M
= parseIR(Ctx
, R
"(
202 define dso_local void @fun() local_unnamed_addr #0 !dbg !9 {
204 call void @llvm.dbg.declare(metadata !{}, metadata !13, metadata !DIExpression()), !dbg !16
208 declare void @llvm.dbg.declare(metadata, metadata, metadata)
211 !llvm.module.flags = !{!2, !3}
214 !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)
215 !1 = !DIFile(filename: "test
.c
", directory: "/")
216 !2 = !{i32 7, !"Dwarf Version
", i32 5}
217 !3 = !{i32 2, !"Debug Info Version
", i32 3}
218 !8 = !{!"clang version
16.0.0"}
219 !9 = distinct !DISubprogram(name: "fun
", scope: !1, file: !1, line: 1, type: !10, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
220 !10 = !DISubroutineType(types: !11)
223 !13 = !DILocalVariable(name: "a
", scope: !9, file: !1, line: 1, type: !14)
224 !14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
225 !16 = !DILocation(line: 1, column: 21, scope: !9)
228 bool BrokenDebugInfo
= true;
229 verifyModule(*M
, &errs(), &BrokenDebugInfo
);
230 ASSERT_FALSE(BrokenDebugInfo
);
232 // Get the dbg.declare.
233 Function
&F
= *cast
<Function
>(M
->getNamedValue("fun"));
234 DbgVariableRecord
*DbgDeclare
=
235 cast
<DbgVariableRecord
>(&*F
.front().front().getDbgRecordRange().begin());
236 // Check that this form counts as a "no location" marker.
237 EXPECT_TRUE(DbgDeclare
->isKillLocation());
240 // Duplicate of above test, but in DbgVariableRecord representation.
241 TEST(MetadataTest
, DeleteInstUsedByDbgVariableRecord
) {
243 bool OldDbgValueMode
= UseNewDbgInfoFormat
;
244 UseNewDbgInfoFormat
= true;
246 std::unique_ptr
<Module
> M
= parseIR(C
, R
"(
247 define i16 @f(i16 %a) !dbg !6 {
248 %b = add i16 %a, 1, !dbg !11
249 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11
250 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
253 declare void @llvm.dbg.value(metadata, metadata, metadata) #0
254 attributes #0 = { nounwind readnone speculatable willreturn }
257 !llvm.module.flags = !{!5}
259 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify
", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
260 !1 = !DIFile(filename: "t
.ll
", directory: "/")
262 !5 = !{i32 2, !"Debug Info Version
", i32 3}
263 !6 = distinct !DISubprogram(name: "foo
", linkageName: "foo
", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
264 !7 = !DISubroutineType(types: !2)
266 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
267 !10 = !DIBasicType(name: "ty16
", size: 16, encoding: DW_ATE_unsigned)
268 !11 = !DILocation(line: 1, column: 1, scope: !6)
271 Instruction
&I
= *M
->getFunction("f")->getEntryBlock().getFirstNonPHI();
273 // Find the DbgVariableRecords using %b.
274 SmallVector
<DbgValueInst
*, 2> DVIs
;
275 SmallVector
<DbgVariableRecord
*, 2> DVRs
;
276 findDbgValues(DVIs
, &I
, &DVRs
);
277 ASSERT_EQ(DVRs
.size(), 2u);
279 // Delete %b. The DbgVariableRecord should now point to undef.
281 EXPECT_EQ(DVRs
[0]->getNumVariableLocationOps(), 1u);
282 EXPECT_TRUE(isa
<UndefValue
>(DVRs
[0]->getVariableLocationOp(0)));
283 EXPECT_TRUE(DVRs
[0]->isKillLocation());
284 EXPECT_EQ(DVRs
[1]->getNumVariableLocationOps(), 2u);
285 EXPECT_TRUE(isa
<UndefValue
>(DVRs
[1]->getVariableLocationOp(1)));
286 EXPECT_TRUE(DVRs
[1]->isKillLocation());
287 UseNewDbgInfoFormat
= OldDbgValueMode
;
290 // Ensure that the order of dbg.value intrinsics returned by findDbgValues, and
291 // their corresponding DbgVariableRecord representation, are consistent.
292 TEST(MetadataTest
, OrderingOfDbgVariableRecords
) {
293 bool OldDbgValueMode
= UseNewDbgInfoFormat
;
294 UseNewDbgInfoFormat
= false;
296 std::unique_ptr
<Module
> M
= parseIR(C
, R
"(
297 define i16 @f(i16 %a) !dbg !6 {
298 %b = add i16 %a, 1, !dbg !11
299 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11
300 call void @llvm.dbg.value(metadata i16 %b, metadata !12, metadata !DIExpression()), !dbg !11
303 declare void @llvm.dbg.value(metadata, metadata, metadata) #0
304 attributes #0 = { nounwind readnone speculatable willreturn }
307 !llvm.module.flags = !{!5}
309 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify
", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
310 !1 = !DIFile(filename: "t
.ll
", directory: "/")
312 !5 = !{i32 2, !"Debug Info Version
", i32 3}
313 !6 = distinct !DISubprogram(name: "foo
", linkageName: "foo
", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
314 !7 = !DISubroutineType(types: !2)
316 !9 = !DILocalVariable(name: "foo
", scope: !6, file: !1, line: 1, type: !10)
317 !10 = !DIBasicType(name: "ty16
", size: 16, encoding: DW_ATE_unsigned)
318 !11 = !DILocation(line: 1, column: 1, scope: !6)
319 !12 = !DILocalVariable(name: "bar
", scope: !6, file: !1, line: 1, type: !10)
322 Instruction
&I
= *M
->getFunction("f")->getEntryBlock().getFirstNonPHI();
324 SmallVector
<DbgValueInst
*, 2> DVIs
;
325 SmallVector
<DbgVariableRecord
*, 2> DVRs
;
326 findDbgValues(DVIs
, &I
, &DVRs
);
327 ASSERT_EQ(DVIs
.size(), 2u);
328 ASSERT_EQ(DVRs
.size(), 0u);
330 // The correct order of dbg.values is given by their use-list, which becomes
331 // the reverse order of creation. Thus the dbg.values should come out as
332 // "bar" and then "foo".
333 DILocalVariable
*Var0
= DVIs
[0]->getVariable();
334 EXPECT_TRUE(Var0
->getName() == "bar");
335 DILocalVariable
*Var1
= DVIs
[1]->getVariable();
336 EXPECT_TRUE(Var1
->getName() == "foo");
338 // Now try again, but in DbgVariableRecord form.
341 M
->convertToNewDbgValues();
342 findDbgValues(DVIs
, &I
, &DVRs
);
343 ASSERT_EQ(DVIs
.size(), 0u);
344 ASSERT_EQ(DVRs
.size(), 2u);
346 Var0
= DVRs
[0]->getVariable();
347 EXPECT_TRUE(Var0
->getName() == "bar");
348 Var1
= DVRs
[1]->getVariable();
349 EXPECT_TRUE(Var1
->getName() == "foo");
351 M
->convertFromNewDbgValues();
352 UseNewDbgInfoFormat
= OldDbgValueMode
;
355 TEST(DIBuilder
, CreateFile
) {
357 std::unique_ptr
<Module
> M(new Module("MyModule", Ctx
));
360 DIFile
*F
= DIB
.createFile("main.c", "/");
361 EXPECT_EQ(std::nullopt
, F
->getSource());
363 std::optional
<DIFile::ChecksumInfo
<StringRef
>> Checksum
;
364 std::optional
<StringRef
> Source
;
365 F
= DIB
.createFile("main.c", "/", Checksum
, Source
);
366 EXPECT_EQ(Source
, F
->getSource());
369 F
= DIB
.createFile("main.c", "/", Checksum
, Source
);
370 EXPECT_EQ(Source
, F
->getSource());
373 TEST(DIBuilder
, CreateFortranArrayTypeWithAttributes
) {
375 std::unique_ptr
<Module
> M(new Module("MyModule", Ctx
));
378 DISubrange
*Subrange
= DIB
.getOrCreateSubrange(1,1);
379 SmallVector
<Metadata
*, 4> Subranges
;
380 Subranges
.push_back(Subrange
);
381 DINodeArray Subscripts
= DIB
.getOrCreateArray(Subranges
);
383 auto getDIExpression
= [&DIB
](int offset
) {
384 SmallVector
<uint64_t, 4> ops
;
385 ops
.push_back(llvm::dwarf::DW_OP_push_object_address
);
386 DIExpression::appendOffset(ops
, offset
);
387 ops
.push_back(llvm::dwarf::DW_OP_deref
);
389 return DIB
.createExpression(ops
);
392 DIFile
*F
= DIB
.createFile("main.c", "/");
393 DICompileUnit
*CU
= DIB
.createCompileUnit(
394 dwarf::DW_LANG_C
, DIB
.createFile("main.c", "/"), "llvm-c", true, "", 0);
396 DIVariable
*DataLocation
=
397 DIB
.createTempGlobalVariableFwdDecl(CU
, "dl", "_dl", F
, 1, nullptr, true);
398 DIExpression
*Associated
= getDIExpression(1);
399 DIExpression
*Allocated
= getDIExpression(2);
400 DIExpression
*Rank
= DIB
.createConstantValueExpression(3);
402 DICompositeType
*ArrayType
= DIB
.createArrayType(0, 0, nullptr, Subscripts
,
403 DataLocation
, Associated
,
406 EXPECT_TRUE(isa_and_nonnull
<DICompositeType
>(ArrayType
));
407 EXPECT_EQ(ArrayType
->getRawDataLocation(), DataLocation
);
408 EXPECT_EQ(ArrayType
->getRawAssociated(), Associated
);
409 EXPECT_EQ(ArrayType
->getRawAllocated(), Allocated
);
410 EXPECT_EQ(ArrayType
->getRawRank(), Rank
);
412 // Avoid memory leak.
413 DIVariable::deleteTemporary(DataLocation
);
416 TEST(DIBuilder
, CreateSetType
) {
418 std::unique_ptr
<Module
> M(new Module("MyModule", Ctx
));
420 DIScope
*Scope
= DISubprogram::getDistinct(
421 Ctx
, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0,
422 DINode::FlagZero
, DISubprogram::SPFlagZero
, nullptr);
423 DIType
*Type
= DIB
.createBasicType("Int", 64, dwarf::DW_ATE_signed
);
424 DIFile
*F
= DIB
.createFile("main.c", "/");
426 DIDerivedType
*SetType
= DIB
.createSetType(Scope
, "set1", F
, 1, 64, 64, Type
);
427 EXPECT_TRUE(isa_and_nonnull
<DIDerivedType
>(SetType
));
430 TEST(DIBuilder
, CreateStringType
) {
432 std::unique_ptr
<Module
> M(new Module("MyModule", Ctx
));
434 DIScope
*Scope
= DISubprogram::getDistinct(
435 Ctx
, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0,
436 DINode::FlagZero
, DISubprogram::SPFlagZero
, nullptr);
437 DIFile
*F
= DIB
.createFile("main.c", "/");
438 StringRef StrName
= "string";
439 DIVariable
*StringLen
= DIB
.createAutoVariable(Scope
, StrName
, F
, 0, nullptr,
440 false, DINode::FlagZero
, 0);
441 auto getDIExpression
= [&DIB
](int offset
) {
442 SmallVector
<uint64_t, 4> ops
;
443 ops
.push_back(llvm::dwarf::DW_OP_push_object_address
);
444 DIExpression::appendOffset(ops
, offset
);
445 ops
.push_back(llvm::dwarf::DW_OP_deref
);
447 return DIB
.createExpression(ops
);
449 DIExpression
*StringLocationExp
= getDIExpression(1);
450 DIStringType
*StringType
=
451 DIB
.createStringType(StrName
, StringLen
, StringLocationExp
);
453 EXPECT_TRUE(isa_and_nonnull
<DIStringType
>(StringType
));
454 EXPECT_EQ(StringType
->getName(), StrName
);
455 EXPECT_EQ(StringType
->getStringLength(), StringLen
);
456 EXPECT_EQ(StringType
->getStringLocationExp(), StringLocationExp
);
458 StringRef StrNameExp
= "stringexp";
459 DIExpression
*StringLengthExp
= getDIExpression(2);
460 DIStringType
*StringTypeExp
=
461 DIB
.createStringType(StrNameExp
, StringLengthExp
, StringLocationExp
);
463 EXPECT_TRUE(isa_and_nonnull
<DIStringType
>(StringTypeExp
));
464 EXPECT_EQ(StringTypeExp
->getName(), StrNameExp
);
465 EXPECT_EQ(StringTypeExp
->getStringLocationExp(), StringLocationExp
);
466 EXPECT_EQ(StringTypeExp
->getStringLengthExp(), StringLengthExp
);
469 TEST(DIBuilder
, DIEnumerator
) {
471 std::unique_ptr
<Module
> M(new Module("MyModule", Ctx
));
473 APSInt
I1(APInt(32, 1));
474 APSInt
I2(APInt(33, 1));
476 auto *E
= DIEnumerator::get(Ctx
, I1
, I1
.isSigned(), "name");
479 auto *E1
= DIEnumerator::getIfExists(Ctx
, I1
, I1
.isSigned(), "name");
482 auto *E2
= DIEnumerator::getIfExists(Ctx
, I2
, I1
.isSigned(), "name");
486 TEST(DbgAssignIntrinsicTest
, replaceVariableLocationOp
) {
488 std::unique_ptr
<Module
> M
= parseIR(C
, R
"(
489 define dso_local void @fun(i32 %v1, ptr %p1, ptr %p2) !dbg !7 {
491 call void @llvm.dbg.assign(metadata i32 %v1, metadata !14, metadata !DIExpression(), metadata !17, metadata ptr %p1, metadata !DIExpression()), !dbg !16
495 declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
498 !llvm.module.flags = !{!3}
500 !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)
501 !1 = !DIFile(filename: "test
.cpp
", directory: "/")
502 !3 = !{i32 2, !"Debug Info Version
", i32 3}
503 !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)
504 !8 = !DISubroutineType(types: !9)
506 !10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
508 !14 = !DILocalVariable(name: "Local
", scope: !7, file: !1, line: 3, type: !10)
509 !16 = !DILocation(line: 0, scope: !7)
510 !17 = distinct !DIAssignID()
512 // Check the test IR isn't malformed.
515 Function
&Fun
= *M
->getFunction("fun");
516 Value
*V1
= Fun
.getArg(0);
517 Value
*P1
= Fun
.getArg(1);
518 Value
*P2
= Fun
.getArg(2);
519 DbgVariableRecord
*DbgAssign
= cast
<DbgVariableRecord
>(
520 &*Fun
.front().front().getDbgRecordRange().begin());
521 ASSERT_TRUE(V1
== DbgAssign
->getVariableLocationOp(0));
522 ASSERT_TRUE(P1
== DbgAssign
->getAddress());
524 #define TEST_REPLACE(Old, New, ExpectedValue, ExpectedAddr) \
525 DbgAssign->replaceVariableLocationOp(Old, New); \
526 EXPECT_EQ(DbgAssign->getVariableLocationOp(0), ExpectedValue); \
527 EXPECT_EQ(DbgAssign->getAddress(), ExpectedAddr);
529 // Replace address only.
530 TEST_REPLACE(/*Old*/ P1
, /*New*/ P2
, /*Value*/ V1
, /*Address*/ P2
);
531 // Replace value only.
532 TEST_REPLACE(/*Old*/ V1
, /*New*/ P2
, /*Value*/ P2
, /*Address*/ P2
);
534 TEST_REPLACE(/*Old*/ P2
, /*New*/ P1
, /*Value*/ P1
, /*Address*/ P1
);
536 // Replace address only, value uses a DIArgList.
537 // Value = {DIArgList(V1)}, Addr = P1.
538 DbgAssign
->setRawLocation(DIArgList::get(C
, ValueAsMetadata::get(V1
)));
539 DbgAssign
->setExpression(DIExpression::get(
540 C
, {dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_stack_value
}));
541 TEST_REPLACE(/*Old*/ P1
, /*New*/ P2
, /*Value*/ V1
, /*Address*/ P2
);
545 TEST(AssignmentTrackingTest
, Utils
) {
546 // Test the assignment tracking utils defined in DebugInfo.h namespace at {}.
548 // getAssignmentInsts
549 // getAssignmentMarkers
553 // The input IR includes two functions, fun1 and fun2. Both contain an alloca
554 // with a DIAssignID tag. fun1's alloca is linked to two llvm.dbg.assign
555 // intrinsics, one of which is for an inlined variable and appears before the
559 std::unique_ptr
<Module
> M
= parseIR(C
, R
"(
560 define dso_local void @fun1() !dbg !7 {
562 call void @llvm.dbg.assign(metadata i32 undef, metadata !10, metadata !DIExpression(), metadata !12, metadata i32 undef, metadata !DIExpression()), !dbg !13
563 %local = alloca i32, align 4, !DIAssignID !12
564 call void @llvm.dbg.assign(metadata i32 undef, metadata !16, metadata !DIExpression(), metadata !12, metadata i32 undef, metadata !DIExpression()), !dbg !15
568 define dso_local void @fun2() !dbg !17 {
570 %local = alloca i32, align 4, !DIAssignID !20
571 call void @llvm.dbg.assign(metadata i32 undef, metadata !18, metadata !DIExpression(), metadata !20, metadata i32 undef, metadata !DIExpression()), !dbg !19
575 define dso_local void @fun3() !dbg !21 {
577 %local = alloca i32, align 4, !DIAssignID !24
578 call void @llvm.dbg.assign(metadata i32 undef, metadata !22, metadata !DIExpression(), metadata !24, metadata i32* undef, metadata !DIExpression()), !dbg !23
582 declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
585 !llvm.module.flags = !{!3, !4, !5}
588 !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)
589 !1 = !DIFile(filename: "test
.c
", directory: "/")
591 !3 = !{i32 7, !"Dwarf Version
", i32 4}
592 !4 = !{i32 2, !"Debug Info Version
", i32 3}
593 !5 = !{i32 1, !"wchar_size
", i32 4}
594 !6 = !{!"clang version
14.0.0"}
595 !7 = distinct !DISubprogram(name: "fun1
", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
596 !8 = !DISubroutineType(types: !9)
598 !10 = !DILocalVariable(name: "local3
", scope: !14, file: !1, line: 2, type: !11)
599 !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
600 !12 = distinct !DIAssignID()
601 !13 = !DILocation(line: 5, column: 1, scope: !14, inlinedAt: !15)
602 !14 = distinct !DISubprogram(name: "inline", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
603 !15 = !DILocation(line: 3, column: 1, scope: !7)
604 !16 = !DILocalVariable(name: "local1
", scope: !7, file: !1, line: 2, type: !11)
605 !17 = distinct !DISubprogram(name: "fun2
", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
606 !18 = !DILocalVariable(name: "local2
", scope: !17, file: !1, line: 2, type: !11)
607 !19 = !DILocation(line: 4, column: 1, scope: !17)
608 !20 = distinct !DIAssignID()
609 !21 = distinct !DISubprogram(name: "fun3
", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
610 !22 = !DILocalVariable(name: "local4
", scope: !21, file: !1, line: 2, type: !11)
611 !23 = !DILocation(line: 4, column: 1, scope: !21)
612 !24 = distinct !DIAssignID()
615 // Check the test IR isn't malformed.
618 Function
&Fun1
= *M
->getFunction("fun1");
619 Instruction
&Alloca
= *Fun1
.getEntryBlock().getFirstNonPHIOrDbg();
621 // 1. Check the Instruction <-> Intrinsic mappings work in fun1.
623 // Check there are two llvm.dbg.assign intrinsics linked to Alloca.
624 auto CheckFun1Mapping
= [&Alloca
]() {
625 auto Markers
= at::getDVRAssignmentMarkers(&Alloca
);
626 EXPECT_TRUE(std::distance(Markers
.begin(), Markers
.end()) == 2);
627 // Check those two entries are distinct.
628 DbgVariableRecord
*First
= *Markers
.begin();
629 DbgVariableRecord
*Second
= *std::next(Markers
.begin());
630 EXPECT_NE(First
, Second
);
632 // Check that we can get back to Alloca from each llvm.dbg.assign.
633 for (auto *DAI
: Markers
) {
634 auto Insts
= at::getAssignmentInsts(DAI
);
635 // Check there is exactly one instruction linked to each intrinsic. Use
636 // ASSERT_TRUE because we're going to dereference the begin iterator.
637 ASSERT_TRUE(std::distance(Insts
.begin(), Insts
.end()) == 1);
638 EXPECT_FALSE(Insts
.empty());
639 // Check the linked instruction is Alloca.
640 Instruction
*LinkedInst
= *Insts
.begin();
641 EXPECT_EQ(LinkedInst
, &Alloca
);
646 // 2. Check DIAssignID RAUW replaces attachments and uses.
649 cast_or_null
<DIAssignID
>(Alloca
.getMetadata(LLVMContext::MD_DIAssignID
));
650 DIAssignID
*New
= DIAssignID::getDistinct(C
);
651 ASSERT_TRUE(Old
&& New
&& New
!= Old
);
653 // Check fun1's alloca and intrinsics have been updated and the mapping still
655 EXPECT_EQ(New
, cast_or_null
<DIAssignID
>(
656 Alloca
.getMetadata(LLVMContext::MD_DIAssignID
)));
659 // Check that fun2's alloca and intrinsic have not not been updated.
660 Instruction
&Fun2Alloca
=
661 *M
->getFunction("fun2")->getEntryBlock().getFirstNonPHIOrDbg();
662 DIAssignID
*Fun2ID
= cast_or_null
<DIAssignID
>(
663 Fun2Alloca
.getMetadata(LLVMContext::MD_DIAssignID
));
664 EXPECT_NE(New
, Fun2ID
);
665 auto Fun2Markers
= at::getDVRAssignmentMarkers(&Fun2Alloca
);
666 ASSERT_TRUE(std::distance(Fun2Markers
.begin(), Fun2Markers
.end()) == 1);
667 auto Fun2Insts
= at::getAssignmentInsts(*Fun2Markers
.begin());
668 ASSERT_TRUE(std::distance(Fun2Insts
.begin(), Fun2Insts
.end()) == 1);
669 EXPECT_EQ(*Fun2Insts
.begin(), &Fun2Alloca
);
671 // 3. Check that deleting dbg.assigns from a specific instruction works.
672 Instruction
&Fun3Alloca
=
673 *M
->getFunction("fun3")->getEntryBlock().getFirstNonPHIOrDbg();
674 auto Fun3Markers
= at::getDVRAssignmentMarkers(&Fun3Alloca
);
675 ASSERT_TRUE(std::distance(Fun3Markers
.begin(), Fun3Markers
.end()) == 1);
676 at::deleteAssignmentMarkers(&Fun3Alloca
);
677 Fun3Markers
= at::getDVRAssignmentMarkers(&Fun3Alloca
);
678 EXPECT_EQ(Fun3Markers
.empty(), true);
680 // 4. Check that deleting works and applies only to the target function.
681 at::deleteAll(&Fun1
);
682 // There should now only be the alloca and ret in fun1.
683 EXPECT_EQ(Fun1
.begin()->size(), 2u);
684 // fun2's alloca should have the same DIAssignID and remain linked to its
686 EXPECT_EQ(Fun2ID
, cast_or_null
<DIAssignID
>(
687 Fun2Alloca
.getMetadata(LLVMContext::MD_DIAssignID
)));
688 EXPECT_FALSE(at::getDVRAssignmentMarkers(&Fun2Alloca
).empty());
691 TEST(IRBuilder
, GetSetInsertionPointWithEmptyBasicBlock
) {
693 std::unique_ptr
<BasicBlock
> BB(BasicBlock::Create(C
, "start"));
694 Module
*M
= new Module("module", C
);
695 IRBuilder
<> Builder(BB
.get());
696 Function
*DbgDeclare
= Intrinsic::getDeclaration(M
, Intrinsic::dbg_declare
);
697 Value
*DIV
= MetadataAsValue::get(C
, (Metadata
*)nullptr);
698 SmallVector
<Value
*, 3> Args
= {DIV
, DIV
, DIV
};
699 Builder
.CreateCall(DbgDeclare
, Args
);
700 auto IP
= BB
->getFirstInsertionPt();
701 Builder
.SetInsertPoint(BB
.get(), IP
);
704 TEST(AssignmentTrackingTest
, InstrMethods
) {
705 // Test the assignment tracking Instruction methods.
707 // Instruction::mergeDIAssignID
710 std::unique_ptr
<Module
> M
= parseIR(C
, R
"(
711 define dso_local void @fun() #0 !dbg !8 {
713 %Local = alloca [2 x i32], align 4, !DIAssignID !12
714 call void @llvm.dbg.assign(metadata i1 undef, metadata !13, metadata !DIExpression(), metadata !12, metadata [2 x i32]* %Local, metadata !DIExpression()), !dbg !18
715 %arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* %Local, i64 0, i64 0, !dbg !19
716 store i32 5, i32* %arrayidx, align 4, !dbg !20, !DIAssignID !21
717 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
718 %arrayidx1 = getelementptr inbounds [2 x i32], [2 x i32]* %Local, i64 0, i64 1, !dbg !22
719 store i32 6, i32* %arrayidx1, align 4, !dbg !23, !DIAssignID !24
720 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
724 declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata) #1
727 !llvm.module.flags = !{!2, !3, !4, !5, !6}
730 !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)
731 !1 = !DIFile(filename: "test
.cpp
", directory: "/")
732 !2 = !{i32 7, !"Dwarf Version
", i32 5}
733 !3 = !{i32 2, !"Debug Info Version
", i32 3}
734 !4 = !{i32 1, !"wchar_size
", i32 4}
735 !5 = !{i32 7, !"uwtable
", i32 1}
736 !6 = !{i32 7, !"frame
-pointer
", i32 2}
737 !7 = !{!"clang version
14.0.0"}
738 !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)
739 !9 = !DISubroutineType(types: !10)
742 !12 = distinct !DIAssignID()
743 !13 = !DILocalVariable(name: "Local
", scope: !8, file: !1, line: 2, type: !14)
744 !14 = !DICompositeType(tag: DW_TAG_array_type, baseType: !15, size: 64, elements: !16)
745 !15 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
747 !17 = !DISubrange(count: 2)
748 !18 = !DILocation(line: 0, scope: !8)
749 !19 = !DILocation(line: 3, column: 3, scope: !8)
750 !20 = !DILocation(line: 3, column: 12, scope: !8)
751 !21 = distinct !DIAssignID()
752 !22 = !DILocation(line: 4, column: 3, scope: !8)
753 !23 = !DILocation(line: 4, column: 12, scope: !8)
754 !24 = distinct !DIAssignID()
755 !25 = !DILocation(line: 5, column: 1, scope: !8)
758 // Check the test IR isn't malformed.
760 Function
&Fun
= *M
->getFunction("fun");
761 SmallVector
<Instruction
*> Stores
;
762 for (auto &BB
: Fun
) {
764 if (isa
<StoreInst
>(&I
))
765 Stores
.push_back(&I
);
769 // The test requires (at least) 2 stores.
770 ASSERT_TRUE(Stores
.size() == 2);
771 // Use SetVectors to check that the attachments and markers are unique
772 // (another test requirement).
773 SetVector
<Metadata
*> OrigIDs
;
774 SetVector
<DbgVariableRecord
*> Markers
;
775 for (const Instruction
*SI
: Stores
) {
776 Metadata
*ID
= SI
->getMetadata(LLVMContext::MD_DIAssignID
);
777 ASSERT_TRUE(OrigIDs
.insert(ID
));
778 ASSERT_TRUE(ID
!= nullptr);
779 auto Range
= at::getDVRAssignmentMarkers(SI
);
780 ASSERT_TRUE(std::distance(Range
.begin(), Range
.end()) == 1);
781 ASSERT_TRUE(Markers
.insert(*Range
.begin()));
784 // Test 1 - mergeDIAssignID.
786 // Input store0->mergeDIAssignID(store1)
787 // ----- -------------------------
788 // store0 !x store0 !x
789 // dbg.assign0 !x dbg.assign !x
790 // store1 !y store1 !x
791 // dbg.assign1 !y dbg.assign1 !x
793 Stores
[0]->mergeDIAssignID(Stores
[1]);
794 // Check that the stores share the same ID.
795 Metadata
*NewID0
= Stores
[0]->getMetadata(LLVMContext::MD_DIAssignID
);
796 Metadata
*NewID1
= Stores
[1]->getMetadata(LLVMContext::MD_DIAssignID
);
797 EXPECT_NE(NewID0
, nullptr);
798 EXPECT_EQ(NewID0
, NewID1
);
799 EXPECT_EQ(Markers
[0]->getAssignID(), NewID0
);
800 EXPECT_EQ(Markers
[1]->getAssignID(), NewID0
);
803 // Test 2 - mergeDIAssignID.
805 // Input store0->mergeDIAssignID(store1)
806 // ----- -------------------------
807 // store0 !x store0 !x
808 // dbg.assign0 !x dbg.assign !x
811 Stores
[1]->setMetadata(LLVMContext::MD_DIAssignID
, nullptr);
812 Stores
[0]->mergeDIAssignID(Stores
[1]);
813 // Check that store1 doesn't get a new ID.
814 Metadata
*NewID0
= Stores
[0]->getMetadata(LLVMContext::MD_DIAssignID
);
815 Metadata
*NewID1
= Stores
[1]->getMetadata(LLVMContext::MD_DIAssignID
);
816 EXPECT_NE(NewID0
, nullptr);
817 EXPECT_EQ(NewID1
, nullptr);
818 EXPECT_EQ(Markers
[0]->getAssignID(), NewID0
);
821 // Test 3 - mergeDIAssignID.
823 // Input store1->mergeDIAssignID(store0)
824 // ----- -------------------------
825 // store0 !x store0 !x
826 // dbg.assign0 !x dbg.assign !x
829 Stores
[1]->setMetadata(LLVMContext::MD_DIAssignID
, nullptr);
830 Stores
[1]->mergeDIAssignID(Stores
[0]);
831 // Check that the stores share the same ID (note store1 starts with none).
832 Metadata
*NewID0
= Stores
[0]->getMetadata(LLVMContext::MD_DIAssignID
);
833 Metadata
*NewID1
= Stores
[1]->getMetadata(LLVMContext::MD_DIAssignID
);
834 EXPECT_NE(NewID0
, nullptr);
835 EXPECT_EQ(NewID0
, NewID1
);
836 EXPECT_EQ(Markers
[0]->getAssignID(), NewID0
);
839 // Test 4 - mergeDIAssignID.
841 // Input store1->mergeDIAssignID(store0)
842 // ----- -------------------------
843 // store0 !x store0 !x
844 // dbg.assign0 !x dbg.assign !x
845 // store1 !x store1 !x
847 Stores
[0]->mergeDIAssignID(Stores
[1]);
848 // Check that the stores share the same ID.
849 Metadata
*NewID0
= Stores
[0]->getMetadata(LLVMContext::MD_DIAssignID
);
850 Metadata
*NewID1
= Stores
[1]->getMetadata(LLVMContext::MD_DIAssignID
);
851 EXPECT_NE(NewID0
, nullptr);
852 EXPECT_EQ(NewID0
, NewID1
);
853 EXPECT_EQ(Markers
[0]->getAssignID(), NewID0
);
856 // Test 5 - dropUnknownNonDebugMetadata.
858 // Input store0->dropUnknownNonDebugMetadata()
859 // ----- -------------------------
860 // store0 !x store0 !x
862 Stores
[0]->dropUnknownNonDebugMetadata();
863 Metadata
*NewID0
= Stores
[0]->getMetadata(LLVMContext::MD_DIAssignID
);
864 EXPECT_NE(NewID0
, nullptr);
868 // Test some very straight-forward operations on DbgVariableRecords -- these are
869 // dbg.values that have been converted to a non-instruction format.
870 TEST(MetadataTest
, ConvertDbgToDbgVariableRecord
) {
872 bool OldDbgValueMode
= UseNewDbgInfoFormat
;
873 UseNewDbgInfoFormat
= false;
874 std::unique_ptr
<Module
> M
= parseIR(C
, R
"(
875 define i16 @f(i16 %a) !dbg !6 {
876 call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11
877 %b = add i16 %a, 1, !dbg !11
878 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11
882 %c = add i16 %b, 1, !dbg !11
885 declare void @llvm.dbg.value(metadata, metadata, metadata) #0
886 attributes #0 = { nounwind readnone speculatable willreturn }
889 !llvm.module.flags = !{!5}
891 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify
", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
892 !1 = !DIFile(filename: "t
.ll
", directory: "/")
894 !5 = !{i32 2, !"Debug Info Version
", i32 3}
895 !6 = distinct !DISubprogram(name: "foo
", linkageName: "foo
", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
896 !7 = !DISubroutineType(types: !2)
898 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
899 !10 = !DIBasicType(name: "ty16
", size: 16, encoding: DW_ATE_unsigned)
900 !11 = !DILocation(line: 1, column: 1, scope: !6)
903 // Find the first dbg.value,
904 Instruction
&I
= *M
->getFunction("f")->getEntryBlock().getFirstNonPHI();
905 const DILocalVariable
*Var
= nullptr;
906 const DIExpression
*Expr
= nullptr;
907 const DILocation
*Loc
= nullptr;
908 const Metadata
*MLoc
= nullptr;
909 DbgVariableRecord
*DVR1
= nullptr;
911 DbgValueInst
*DPI
= dyn_cast
<DbgValueInst
>(&I
);
913 Var
= DPI
->getVariable();
914 Expr
= DPI
->getExpression();
915 Loc
= DPI
->getDebugLoc().get();
916 MLoc
= DPI
->getRawLocation();
918 // Test the creation of a DbgVariableRecord and it's conversion back to a
920 DVR1
= new DbgVariableRecord(DPI
);
921 EXPECT_EQ(DVR1
->getVariable(), Var
);
922 EXPECT_EQ(DVR1
->getExpression(), Expr
);
923 EXPECT_EQ(DVR1
->getDebugLoc().get(), Loc
);
924 EXPECT_EQ(DVR1
->getRawLocation(), MLoc
);
927 DPI
->eraseFromParent();
928 // Re-create from DVR1, inserting at front.
929 DVR1
->createDebugIntrinsic(&*M
,
930 &M
->getFunction("f")->getEntryBlock().front());
932 Instruction
*NewDPI
= &M
->getFunction("f")->getEntryBlock().front();
933 DbgValueInst
*DPI2
= dyn_cast
<DbgValueInst
>(NewDPI
);
935 EXPECT_EQ(DPI2
->getVariable(), Var
);
936 EXPECT_EQ(DPI2
->getExpression(), Expr
);
937 EXPECT_EQ(DPI2
->getDebugLoc().get(), Loc
);
938 EXPECT_EQ(DPI2
->getRawLocation(), MLoc
);
941 // Fetch the second dbg.value, convert it to a DbgVariableRecord,
942 BasicBlock::iterator It
= M
->getFunction("f")->getEntryBlock().begin();
943 It
= std::next(std::next(It
));
944 DbgValueInst
*DPI3
= dyn_cast
<DbgValueInst
>(It
);
946 DbgVariableRecord
*DVR2
= new DbgVariableRecord(DPI3
);
948 // These dbg.values are supposed to refer to different values.
949 EXPECT_NE(DVR1
->getRawLocation(), DVR2
->getRawLocation());
951 // Try manipulating DbgVariableRecords and markers in the exit block.
952 BasicBlock
*ExitBlock
= &*std::next(M
->getFunction("f")->getEntryBlock().getIterator());
953 Instruction
*FirstInst
= &ExitBlock
->front();
954 Instruction
*RetInst
= &*std::next(FirstInst
->getIterator());
956 // Set-up DbgMarkers in this block.
957 ExitBlock
->IsNewDbgInfoFormat
= true;
958 ExitBlock
->createMarker(FirstInst
);
959 ExitBlock
->createMarker(RetInst
);
961 // Insert DbgRecords into markers, order should come out DVR2, DVR1.
962 FirstInst
->DebugMarker
->insertDbgRecord(DVR1
, false);
963 FirstInst
->DebugMarker
->insertDbgRecord(DVR2
, true);
964 unsigned int ItCount
= 0;
965 for (DbgRecord
&Item
: FirstInst
->DebugMarker
->getDbgRecordRange()) {
966 EXPECT_TRUE((&Item
== DVR2
&& ItCount
== 0) ||
967 (&Item
== DVR1
&& ItCount
== 1));
968 EXPECT_EQ(Item
.getMarker(), FirstInst
->DebugMarker
);
972 // Clone them onto the second marker -- should allocate new DVRs.
973 RetInst
->DebugMarker
->cloneDebugInfoFrom(FirstInst
->DebugMarker
, std::nullopt
,
975 EXPECT_EQ(RetInst
->DebugMarker
->StoredDbgRecords
.size(), 2u);
977 // Check these things store the same information; but that they're not the same
979 for (DbgVariableRecord
&Item
:
980 filterDbgVars(RetInst
->DebugMarker
->getDbgRecordRange())) {
982 (Item
.getRawLocation() == DVR2
->getRawLocation() && ItCount
== 0) ||
983 (Item
.getRawLocation() == DVR1
->getRawLocation() && ItCount
== 1));
985 EXPECT_EQ(Item
.getMarker(), RetInst
->DebugMarker
);
986 EXPECT_NE(&Item
, DVR1
);
987 EXPECT_NE(&Item
, DVR2
);
991 RetInst
->DebugMarker
->dropDbgRecords();
992 EXPECT_EQ(RetInst
->DebugMarker
->StoredDbgRecords
.size(), 0u);
994 // Try cloning one single DbgVariableRecord.
995 auto DIIt
= std::next(FirstInst
->DebugMarker
->getDbgRecordRange().begin());
996 RetInst
->DebugMarker
->cloneDebugInfoFrom(FirstInst
->DebugMarker
, DIIt
, false);
997 EXPECT_EQ(RetInst
->DebugMarker
->StoredDbgRecords
.size(), 1u);
998 // The second DbgVariableRecord should have been cloned; it should have the
999 // same values as DVR1.
1001 cast
<DbgVariableRecord
>(RetInst
->DebugMarker
->StoredDbgRecords
.begin())
1003 DVR1
->getRawLocation());
1004 // We should be able to drop individual DbgRecords.
1005 RetInst
->DebugMarker
->dropOneDbgRecord(
1006 &*RetInst
->DebugMarker
->StoredDbgRecords
.begin());
1008 // "Aborb" a DbgMarker: this means pretend that the instruction it's attached
1009 // to is disappearing so it needs to be transferred into "this" marker.
1010 RetInst
->DebugMarker
->absorbDebugValues(*FirstInst
->DebugMarker
, true);
1011 EXPECT_EQ(RetInst
->DebugMarker
->StoredDbgRecords
.size(), 2u);
1012 // Should be the DVR1 and DVR2 objects.
1014 for (DbgRecord
&Item
: RetInst
->DebugMarker
->getDbgRecordRange()) {
1015 EXPECT_TRUE((&Item
== DVR2
&& ItCount
== 0) ||
1016 (&Item
== DVR1
&& ItCount
== 1));
1017 EXPECT_EQ(Item
.getMarker(), RetInst
->DebugMarker
);
1021 // Finally -- there are two DbgVariableRecords left over. If we remove
1022 // evrything in the basic block, then they should sink down into the
1023 // "TrailingDbgRecords" container for dangling debug-info. Future facilities
1024 // will restore them back when a terminator is inserted.
1025 FirstInst
->DebugMarker
->removeMarker();
1026 FirstInst
->eraseFromParent();
1027 RetInst
->DebugMarker
->removeMarker();
1028 RetInst
->eraseFromParent();
1030 DbgMarker
*EndMarker
= ExitBlock
->getTrailingDbgRecords();
1031 ASSERT_NE(EndMarker
, nullptr);
1032 EXPECT_EQ(EndMarker
->StoredDbgRecords
.size(), 2u);
1033 // Test again that it's those two DbgVariableRecords, DVR1 and DVR2.
1035 for (DbgRecord
&Item
: EndMarker
->getDbgRecordRange()) {
1036 EXPECT_TRUE((&Item
== DVR2
&& ItCount
== 0) ||
1037 (&Item
== DVR1
&& ItCount
== 1));
1038 EXPECT_EQ(Item
.getMarker(), EndMarker
);
1042 // Cleanup the trailing DbgVariableRecord records and marker.
1043 EndMarker
->eraseFromParent();
1045 // The record of those trailing DbgVariableRecords would dangle and cause an
1046 // assertion failure if it lived until the end of the LLVMContext.
1047 ExitBlock
->deleteTrailingDbgRecords();
1048 UseNewDbgInfoFormat
= OldDbgValueMode
;
1051 TEST(MetadataTest
, DbgVariableRecordConversionRoutines
) {
1054 bool OldDbgValueMode
= UseNewDbgInfoFormat
;
1055 UseNewDbgInfoFormat
= false;
1057 std::unique_ptr
<Module
> M
= parseIR(C
, R
"(
1058 define i16 @f(i16 %a) !dbg !6 {
1059 call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11
1060 %b = add i16 %a, 1, !dbg !11
1061 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11
1065 %c = add i16 %b, 1, !dbg !11
1068 declare void @llvm.dbg.value(metadata, metadata, metadata) #0
1069 attributes #0 = { nounwind readnone speculatable willreturn }
1071 !llvm.dbg.cu = !{!0}
1072 !llvm.module.flags = !{!5}
1074 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify
", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
1075 !1 = !DIFile(filename: "t
.ll
", directory: "/")
1077 !5 = !{i32 2, !"Debug Info Version
", i32 3}
1078 !6 = distinct !DISubprogram(name: "foo
", linkageName: "foo
", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
1079 !7 = !DISubroutineType(types: !2)
1081 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
1082 !10 = !DIBasicType(name: "ty16
", size: 16, encoding: DW_ATE_unsigned)
1083 !11 = !DILocation(line: 1, column: 1, scope: !6)
1086 // For the purpose of this test, set and un-set the command line option
1087 // corresponding to UseNewDbgInfoFormat, but only after parsing, to ensure
1088 // that the IR starts off in the old format.
1089 UseNewDbgInfoFormat
= true;
1091 // Check that the conversion routines and utilities between dbg.value
1092 // debug-info format and DbgVariableRecords works.
1093 Function
*F
= M
->getFunction("f");
1094 BasicBlock
*BB1
= &F
->getEntryBlock();
1095 // First instruction should be a dbg.value.
1096 EXPECT_TRUE(isa
<DbgValueInst
>(BB1
->front()));
1097 EXPECT_FALSE(BB1
->IsNewDbgInfoFormat
);
1098 // Validating the block for DbgVariableRecords / DbgMarkers shouldn't fail --
1099 // there's no data stored right now.
1100 bool BrokenDebugInfo
= false;
1101 bool Error
= verifyModule(*M
, &errs(), &BrokenDebugInfo
);
1102 EXPECT_FALSE(Error
);
1103 EXPECT_FALSE(BrokenDebugInfo
);
1105 // Function and module should be marked as not having the new format too.
1106 EXPECT_FALSE(F
->IsNewDbgInfoFormat
);
1107 EXPECT_FALSE(M
->IsNewDbgInfoFormat
);
1110 M
->convertToNewDbgValues();
1111 EXPECT_TRUE(M
->IsNewDbgInfoFormat
);
1112 EXPECT_TRUE(F
->IsNewDbgInfoFormat
);
1113 EXPECT_TRUE(BB1
->IsNewDbgInfoFormat
);
1115 // There should now be no dbg.value instructions!
1116 // Ensure the first instruction exists, the test all of them.
1117 EXPECT_FALSE(isa
<DbgValueInst
>(BB1
->front()));
1120 EXPECT_FALSE(isa
<DbgValueInst
>(I
));
1122 // There should be a DbgMarker on each of the two instructions in the entry
1123 // block, each containing one DbgVariableRecord.
1124 EXPECT_EQ(BB1
->size(), 2u);
1125 Instruction
*FirstInst
= &BB1
->front();
1126 Instruction
*SecondInst
= FirstInst
->getNextNode();
1127 ASSERT_TRUE(FirstInst
->DebugMarker
);
1128 ASSERT_TRUE(SecondInst
->DebugMarker
);
1129 EXPECT_NE(FirstInst
->DebugMarker
, SecondInst
->DebugMarker
);
1130 EXPECT_EQ(FirstInst
, FirstInst
->DebugMarker
->MarkedInstr
);
1131 EXPECT_EQ(SecondInst
, SecondInst
->DebugMarker
->MarkedInstr
);
1133 EXPECT_EQ(FirstInst
->DebugMarker
->StoredDbgRecords
.size(), 1u);
1134 DbgVariableRecord
*DVR1
= cast
<DbgVariableRecord
>(
1135 &*FirstInst
->DebugMarker
->getDbgRecordRange().begin());
1136 EXPECT_EQ(DVR1
->getMarker(), FirstInst
->DebugMarker
);
1137 // Should point at %a, an argument.
1138 EXPECT_TRUE(isa
<Argument
>(DVR1
->getVariableLocationOp(0)));
1140 EXPECT_EQ(SecondInst
->DebugMarker
->StoredDbgRecords
.size(), 1u);
1141 DbgVariableRecord
*DVR2
= cast
<DbgVariableRecord
>(
1142 &*SecondInst
->DebugMarker
->getDbgRecordRange().begin());
1143 EXPECT_EQ(DVR2
->getMarker(), SecondInst
->DebugMarker
);
1144 // Should point at FirstInst.
1145 EXPECT_EQ(DVR2
->getVariableLocationOp(0), FirstInst
);
1147 // There should be no DbgVariableRecords / DbgMarkers in the second block, but
1148 // it should be marked as being in the new format.
1149 BasicBlock
*BB2
= BB1
->getNextNode();
1150 EXPECT_TRUE(BB2
->IsNewDbgInfoFormat
);
1151 for (auto &Inst
: *BB2
)
1152 // Either there should be no marker, or it should be empty.
1153 EXPECT_TRUE(!Inst
.DebugMarker
||
1154 Inst
.DebugMarker
->StoredDbgRecords
.empty());
1156 // Validating the first block should continue to not be a problem,
1157 Error
= verifyModule(*M
, &errs(), &BrokenDebugInfo
);
1158 EXPECT_FALSE(Error
);
1159 EXPECT_FALSE(BrokenDebugInfo
);
1160 // But if we were to break something, it should be able to fire. Don't attempt
1161 // to comprehensively test the validator, it's a smoke-test rather than a
1162 // "proper" verification pass.
1163 DVR1
->setMarker(nullptr);
1164 // A marker pointing the wrong way should be an error.
1165 Error
= verifyModule(*M
, &errs(), &BrokenDebugInfo
);
1166 EXPECT_FALSE(Error
);
1167 EXPECT_TRUE(BrokenDebugInfo
);
1168 DVR1
->setMarker(FirstInst
->DebugMarker
);
1170 DILocalVariable
*DLV1
= DVR1
->getVariable();
1171 DIExpression
*Expr1
= DVR1
->getExpression();
1172 DILocalVariable
*DLV2
= DVR2
->getVariable();
1173 DIExpression
*Expr2
= DVR2
->getExpression();
1175 // Convert everything back to the "old" format and ensure it's right.
1176 M
->convertFromNewDbgValues();
1177 EXPECT_FALSE(M
->IsNewDbgInfoFormat
);
1178 EXPECT_FALSE(F
->IsNewDbgInfoFormat
);
1179 EXPECT_FALSE(BB1
->IsNewDbgInfoFormat
);
1181 EXPECT_EQ(BB1
->size(), 4u);
1182 ASSERT_TRUE(isa
<DbgValueInst
>(BB1
->front()));
1183 DbgValueInst
*DVI1
= cast
<DbgValueInst
>(&BB1
->front());
1184 // These dbg.values should still point at the same places.
1185 EXPECT_TRUE(isa
<Argument
>(DVI1
->getVariableLocationOp(0)));
1186 DbgValueInst
*DVI2
= cast
<DbgValueInst
>(DVI1
->getNextNode()->getNextNode());
1187 EXPECT_EQ(DVI2
->getVariableLocationOp(0), FirstInst
);
1189 // Check a few fields too,
1190 EXPECT_EQ(DVI1
->getVariable(), DLV1
);
1191 EXPECT_EQ(DVI1
->getExpression(), Expr1
);
1192 EXPECT_EQ(DVI2
->getVariable(), DLV2
);
1193 EXPECT_EQ(DVI2
->getExpression(), Expr2
);
1195 UseNewDbgInfoFormat
= OldDbgValueMode
;
1198 // Test that the hashing function for DISubprograms representing methods produce
1199 // the same result after replacing their scope (the type containing the
1200 // subprogram) from a temporary DIType with the permanent one.
1201 TEST(DIBuilder
, HashingDISubprogram
) {
1203 std::unique_ptr
<Module
> M
= std::make_unique
<Module
>("MyModule", Ctx
);
1206 DIFile
*F
= DIB
.createFile("main.c", "/");
1208 DIB
.createCompileUnit(dwarf::DW_LANG_C
, F
, "Test", false, "", 0);
1210 llvm::TempDIType ForwardDeclaredType
=
1211 llvm::TempDIType(DIB
.createReplaceableCompositeType(
1212 llvm::dwarf::DW_TAG_structure_type
, "MyType", CU
, F
, 0, 0, 8, 8, {},
1213 "UniqueIdentifier"));
1215 // The hashing function is different for declarations and definitions, so
1216 // create one of each.
1217 DISubprogram
*Declaration
=
1218 DIB
.createMethod(ForwardDeclaredType
.get(), "MethodName", "LinkageName",
1219 F
, 0, DIB
.createSubroutineType({}));
1221 DISubprogram
*Definition
= DIB
.createFunction(
1222 ForwardDeclaredType
.get(), "MethodName", "LinkageName", F
, 0,
1223 DIB
.createSubroutineType({}), 0, DINode::FlagZero
,
1224 llvm::DISubprogram::SPFlagDefinition
, nullptr, Declaration
);
1226 // Produce the hash with the temporary scope.
1227 unsigned HashDeclaration
=
1228 MDNodeKeyImpl
<DISubprogram
>(Declaration
).getHashValue();
1229 unsigned HashDefinition
=
1230 MDNodeKeyImpl
<DISubprogram
>(Definition
).getHashValue();
1232 // Instantiate the real scope and replace the temporary one with it.
1233 DICompositeType
*Type
= DIB
.createStructType(CU
, "MyType", F
, 0, 8, 8, {}, {},
1234 {}, 0, {}, "UniqueIdentifier");
1235 DIB
.replaceTemporary(std::move(ForwardDeclaredType
), Type
);
1237 // Now make sure the hashing is consistent.
1238 unsigned HashDeclarationAfter
=
1239 MDNodeKeyImpl
<DISubprogram
>(Declaration
).getHashValue();
1240 unsigned HashDefinitionAfter
=
1241 MDNodeKeyImpl
<DISubprogram
>(Definition
).getHashValue();
1243 EXPECT_EQ(HashDeclaration
, HashDeclarationAfter
);
1244 EXPECT_EQ(HashDefinition
, HashDefinitionAfter
);