1 //===- llvm/unittest/IR/DebugInfo.cpp - DebugInfo tests -------------------===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 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" 24 25 #include "gtest/gtest.h" 26 27 using namespace llvm; 28 29 extern cl::opt<bool> UseNewDbgInfoFormat; 30 31 static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) { 32 SMDiagnostic Err; 33 std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C); 34 if (!Mod) 35 Err.print("DebugInfoTest", errs()); 36 return Mod; 37 } 38 39 namespace { 40 41 TEST(DINodeTest, getFlag) { 42 // Some valid flags. 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")); 49 50 // FlagAccessibility shouldn't work. 51 EXPECT_EQ(0u, DINode::getFlag("DIFlagAccessibility")); 52 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")); 58 } 59 60 TEST(DINodeTest, getFlagString) { 61 // Some valid flags. 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)); 72 73 // FlagAccessibility actually equals FlagPublic. 74 EXPECT_EQ(StringRef("DIFlagPublic"), 75 DINode::getFlagString(DINode::FlagAccessibility)); 76 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))); 84 } 85 86 TEST(DINodeTest, splitFlags) { 87 // Some valid flags. 88 #define CHECK_SPLIT(FLAGS, VECTOR, REMAINDER) \ 89 { \ 90 SmallVector<DINode::DIFlags, 8> V; \ 91 EXPECT_EQ(REMAINDER, DINode::splitFlags(FLAGS, V)); \ 92 EXPECT_TRUE(ArrayRef(V).equals(VECTOR)); \ 93 } 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}, 99 DINode::FlagZero); 100 DINode::DIFlags Flags[] = {DINode::FlagFwdDecl, DINode::FlagVector}; 101 CHECK_SPLIT(DINode::FlagFwdDecl | DINode::FlagVector, Flags, 102 DINode::FlagZero); 103 CHECK_SPLIT(DINode::FlagZero, {}, DINode::FlagZero); 104 #undef CHECK_SPLIT 105 } 106 107 TEST(StripTest, LoopMetadata) { 108 LLVMContext C; 109 std::unique_ptr<Module> M = parseIR(C, R"( 110 define void @f() !dbg !5 { 111 ret void, !dbg !10, !llvm.loop !11 112 } 113 114 !llvm.dbg.cu = !{!0} 115 !llvm.debugify = !{!3, !3} 116 !llvm.module.flags = !{!4} 117 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: "/") 120 !2 = !{} 121 !3 = !{i32 1} 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) 125 !7 = !{!8} 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} 130 )"); 131 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)) 140 ->getScope() 141 ->getSubprogram() 142 ->getUnit() 143 ->getEmissionKind(); 144 }; 145 146 EXPECT_EQ(getEmissionKind(), DICompileUnit::FullDebug); 147 148 bool Changed = stripNonLineTableDebugInfo(*M); 149 EXPECT_TRUE(Changed); 150 151 EXPECT_EQ(getEmissionKind(), DICompileUnit::LineTablesOnly); 152 153 bool BrokenDebugInfo = false; 154 bool HardError = verifyModule(*M, &errs(), &BrokenDebugInfo); 155 EXPECT_FALSE(HardError); 156 EXPECT_FALSE(BrokenDebugInfo); 157 } 158 159 TEST(MetadataTest, DeleteInstUsedByDbgValue) { 160 LLVMContext C; 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 165 ret i16 0, !dbg !11 166 } 167 declare void @llvm.dbg.value(metadata, metadata, metadata) #0 168 attributes #0 = { nounwind readnone speculatable willreturn } 169 170 !llvm.dbg.cu = !{!0} 171 !llvm.module.flags = !{!5} 172 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: "/") 175 !2 = !{} 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) 179 !8 = !{!9} 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) 183 )"); 184 185 // Find %b = add ... 186 Instruction &I = *M->getFunction("f")->getEntryBlock().getFirstNonPHI(); 187 188 // Find the dbg.value using %b. 189 SmallVector<DbgValueInst *, 1> DVIs; 190 findDbgValues(DVIs, &I); 191 192 // Delete %b. The dbg.value should now point to undef. 193 I.eraseFromParent(); 194 EXPECT_EQ(DVIs[0]->getNumVariableLocationOps(), 1u); 195 EXPECT_TRUE(isa<UndefValue>(DVIs[0]->getValue(0))); 196 } 197 198 TEST(DbgVariableIntrinsic, EmptyMDIsKillLocation) { 199 LLVMContext Ctx; 200 std::unique_ptr<Module> M = parseIR(Ctx, R"( 201 define dso_local void @fun() local_unnamed_addr #0 !dbg !9 { 202 entry: 203 call void @llvm.dbg.declare(metadata !{}, metadata !13, metadata !DIExpression()), !dbg !16 204 ret void, !dbg !16 205 } 206 207 declare void @llvm.dbg.declare(metadata, metadata, metadata) 208 209 !llvm.dbg.cu = !{!0} 210 !llvm.module.flags = !{!2, !3} 211 !llvm.ident = !{!8} 212 213 !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) 214 !1 = !DIFile(filename: "test.c", directory: "/") 215 !2 = !{i32 7, !"Dwarf Version", i32 5} 216 !3 = !{i32 2, !"Debug Info Version", i32 3} 217 !8 = !{!"clang version 16.0.0"} 218 !9 = distinct !DISubprogram(name: "fun", scope: !1, file: !1, line: 1, type: !10, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12) 219 !10 = !DISubroutineType(types: !11) 220 !11 = !{null} 221 !12 = !{!13} 222 !13 = !DILocalVariable(name: "a", scope: !9, file: !1, line: 1, type: !14) 223 !14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 224 !16 = !DILocation(line: 1, column: 21, scope: !9) 225 )"); 226 227 bool BrokenDebugInfo = true; 228 verifyModule(*M, &errs(), &BrokenDebugInfo); 229 ASSERT_FALSE(BrokenDebugInfo); 230 231 // Get the dbg.declare. 232 Function &F = *cast<Function>(M->getNamedValue("fun")); 233 DbgVariableIntrinsic *DbgDeclare = 234 cast<DbgVariableIntrinsic>(&F.front().front()); 235 // Check that this form counts as a "no location" marker. 236 EXPECT_TRUE(DbgDeclare->isKillLocation()); 237 } 238 239 // Duplicate of above test, but in DbgVariableRecord representation. 240 TEST(MetadataTest, DeleteInstUsedByDbgVariableRecord) { 241 LLVMContext C; 242 std::unique_ptr<Module> M = parseIR(C, R"( 243 define i16 @f(i16 %a) !dbg !6 { 244 %b = add i16 %a, 1, !dbg !11 245 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 246 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 ret i16 0, !dbg !11 248 } 249 declare void @llvm.dbg.value(metadata, metadata, metadata) #0 250 attributes #0 = { nounwind readnone speculatable willreturn } 251 252 !llvm.dbg.cu = !{!0} 253 !llvm.module.flags = !{!5} 254 255 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 256 !1 = !DIFile(filename: "t.ll", directory: "/") 257 !2 = !{} 258 !5 = !{i32 2, !"Debug Info Version", i32 3} 259 !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8) 260 !7 = !DISubroutineType(types: !2) 261 !8 = !{!9} 262 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) 263 !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned) 264 !11 = !DILocation(line: 1, column: 1, scope: !6) 265 )"); 266 267 bool OldDbgValueMode = UseNewDbgInfoFormat; 268 UseNewDbgInfoFormat = true; 269 Instruction &I = *M->getFunction("f")->getEntryBlock().getFirstNonPHI(); 270 M->convertToNewDbgValues(); 271 272 // Find the DbgVariableRecords using %b. 273 SmallVector<DbgValueInst *, 2> DVIs; 274 SmallVector<DbgVariableRecord *, 2> DVRs; 275 findDbgValues(DVIs, &I, &DVRs); 276 ASSERT_EQ(DVRs.size(), 2u); 277 278 // Delete %b. The DbgVariableRecord should now point to undef. 279 I.eraseFromParent(); 280 EXPECT_EQ(DVRs[0]->getNumVariableLocationOps(), 1u); 281 EXPECT_TRUE(isa<UndefValue>(DVRs[0]->getVariableLocationOp(0))); 282 EXPECT_TRUE(DVRs[0]->isKillLocation()); 283 EXPECT_EQ(DVRs[1]->getNumVariableLocationOps(), 2u); 284 EXPECT_TRUE(isa<UndefValue>(DVRs[1]->getVariableLocationOp(1))); 285 EXPECT_TRUE(DVRs[1]->isKillLocation()); 286 UseNewDbgInfoFormat = OldDbgValueMode; 287 } 288 289 // Ensure that the order of dbg.value intrinsics returned by findDbgValues, and 290 // their corresponding DbgVariableRecord representation, are consistent. 291 TEST(MetadataTest, OrderingOfDbgVariableRecords) { 292 LLVMContext C; 293 std::unique_ptr<Module> M = parseIR(C, R"( 294 define i16 @f(i16 %a) !dbg !6 { 295 %b = add i16 %a, 1, !dbg !11 296 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 297 call void @llvm.dbg.value(metadata i16 %b, metadata !12, metadata !DIExpression()), !dbg !11 298 ret i16 0, !dbg !11 299 } 300 declare void @llvm.dbg.value(metadata, metadata, metadata) #0 301 attributes #0 = { nounwind readnone speculatable willreturn } 302 303 !llvm.dbg.cu = !{!0} 304 !llvm.module.flags = !{!5} 305 306 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 307 !1 = !DIFile(filename: "t.ll", directory: "/") 308 !2 = !{} 309 !5 = !{i32 2, !"Debug Info Version", i32 3} 310 !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8) 311 !7 = !DISubroutineType(types: !2) 312 !8 = !{!9} 313 !9 = !DILocalVariable(name: "foo", scope: !6, file: !1, line: 1, type: !10) 314 !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned) 315 !11 = !DILocation(line: 1, column: 1, scope: !6) 316 !12 = !DILocalVariable(name: "bar", scope: !6, file: !1, line: 1, type: !10) 317 )"); 318 319 bool OldDbgValueMode = UseNewDbgInfoFormat; 320 UseNewDbgInfoFormat = true; 321 Instruction &I = *M->getFunction("f")->getEntryBlock().getFirstNonPHI(); 322 323 SmallVector<DbgValueInst *, 2> DVIs; 324 SmallVector<DbgVariableRecord *, 2> DVRs; 325 findDbgValues(DVIs, &I, &DVRs); 326 ASSERT_EQ(DVIs.size(), 2u); 327 ASSERT_EQ(DVRs.size(), 0u); 328 329 // The correct order of dbg.values is given by their use-list, which becomes 330 // the reverse order of creation. Thus the dbg.values should come out as 331 // "bar" and then "foo". 332 DILocalVariable *Var0 = DVIs[0]->getVariable(); 333 EXPECT_TRUE(Var0->getName() == "bar"); 334 DILocalVariable *Var1 = DVIs[1]->getVariable(); 335 EXPECT_TRUE(Var1->getName() == "foo"); 336 337 // Now try again, but in DbgVariableRecord form. 338 DVIs.clear(); 339 340 M->convertToNewDbgValues(); 341 findDbgValues(DVIs, &I, &DVRs); 342 ASSERT_EQ(DVIs.size(), 0u); 343 ASSERT_EQ(DVRs.size(), 2u); 344 345 Var0 = DVRs[0]->getVariable(); 346 EXPECT_TRUE(Var0->getName() == "bar"); 347 Var1 = DVRs[1]->getVariable(); 348 EXPECT_TRUE(Var1->getName() == "foo"); 349 350 M->convertFromNewDbgValues(); 351 UseNewDbgInfoFormat = OldDbgValueMode; 352 } 353 354 TEST(DIBuilder, CreateFile) { 355 LLVMContext Ctx; 356 std::unique_ptr<Module> M(new Module("MyModule", Ctx)); 357 DIBuilder DIB(*M); 358 359 DIFile *F = DIB.createFile("main.c", "/"); 360 EXPECT_EQ(std::nullopt, F->getSource()); 361 362 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum; 363 std::optional<StringRef> Source; 364 F = DIB.createFile("main.c", "/", Checksum, Source); 365 EXPECT_EQ(Source, F->getSource()); 366 367 Source = ""; 368 F = DIB.createFile("main.c", "/", Checksum, Source); 369 EXPECT_EQ(Source, F->getSource()); 370 } 371 372 TEST(DIBuilder, CreateFortranArrayTypeWithAttributes) { 373 LLVMContext Ctx; 374 std::unique_ptr<Module> M(new Module("MyModule", Ctx)); 375 DIBuilder DIB(*M); 376 377 DISubrange *Subrange = DIB.getOrCreateSubrange(1,1); 378 SmallVector<Metadata*, 4> Subranges; 379 Subranges.push_back(Subrange); 380 DINodeArray Subscripts = DIB.getOrCreateArray(Subranges); 381 382 auto getDIExpression = [&DIB](int offset) { 383 SmallVector<uint64_t, 4> ops; 384 ops.push_back(llvm::dwarf::DW_OP_push_object_address); 385 DIExpression::appendOffset(ops, offset); 386 ops.push_back(llvm::dwarf::DW_OP_deref); 387 388 return DIB.createExpression(ops); 389 }; 390 391 DIFile *F = DIB.createFile("main.c", "/"); 392 DICompileUnit *CU = DIB.createCompileUnit( 393 dwarf::DW_LANG_C, DIB.createFile("main.c", "/"), "llvm-c", true, "", 0); 394 395 DIVariable *DataLocation = 396 DIB.createTempGlobalVariableFwdDecl(CU, "dl", "_dl", F, 1, nullptr, true); 397 DIExpression *Associated = getDIExpression(1); 398 DIExpression *Allocated = getDIExpression(2); 399 DIExpression *Rank = DIB.createConstantValueExpression(3); 400 401 DICompositeType *ArrayType = DIB.createArrayType(0, 0, nullptr, Subscripts, 402 DataLocation, Associated, 403 Allocated, Rank); 404 405 EXPECT_TRUE(isa_and_nonnull<DICompositeType>(ArrayType)); 406 EXPECT_EQ(ArrayType->getRawDataLocation(), DataLocation); 407 EXPECT_EQ(ArrayType->getRawAssociated(), Associated); 408 EXPECT_EQ(ArrayType->getRawAllocated(), Allocated); 409 EXPECT_EQ(ArrayType->getRawRank(), Rank); 410 411 // Avoid memory leak. 412 DIVariable::deleteTemporary(DataLocation); 413 } 414 415 TEST(DIBuilder, CreateSetType) { 416 LLVMContext Ctx; 417 std::unique_ptr<Module> M(new Module("MyModule", Ctx)); 418 DIBuilder DIB(*M); 419 DIScope *Scope = DISubprogram::getDistinct( 420 Ctx, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0, 421 DINode::FlagZero, DISubprogram::SPFlagZero, nullptr); 422 DIType *Type = DIB.createBasicType("Int", 64, dwarf::DW_ATE_signed); 423 DIFile *F = DIB.createFile("main.c", "/"); 424 425 DIDerivedType *SetType = DIB.createSetType(Scope, "set1", F, 1, 64, 64, Type); 426 EXPECT_TRUE(isa_and_nonnull<DIDerivedType>(SetType)); 427 } 428 429 TEST(DIBuilder, CreateStringType) { 430 LLVMContext Ctx; 431 std::unique_ptr<Module> M(new Module("MyModule", Ctx)); 432 DIBuilder DIB(*M); 433 DIScope *Scope = DISubprogram::getDistinct( 434 Ctx, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0, 435 DINode::FlagZero, DISubprogram::SPFlagZero, nullptr); 436 DIFile *F = DIB.createFile("main.c", "/"); 437 StringRef StrName = "string"; 438 DIVariable *StringLen = DIB.createAutoVariable(Scope, StrName, F, 0, nullptr, 439 false, DINode::FlagZero, 0); 440 auto getDIExpression = [&DIB](int offset) { 441 SmallVector<uint64_t, 4> ops; 442 ops.push_back(llvm::dwarf::DW_OP_push_object_address); 443 DIExpression::appendOffset(ops, offset); 444 ops.push_back(llvm::dwarf::DW_OP_deref); 445 446 return DIB.createExpression(ops); 447 }; 448 DIExpression *StringLocationExp = getDIExpression(1); 449 DIStringType *StringType = 450 DIB.createStringType(StrName, StringLen, StringLocationExp); 451 452 EXPECT_TRUE(isa_and_nonnull<DIStringType>(StringType)); 453 EXPECT_EQ(StringType->getName(), StrName); 454 EXPECT_EQ(StringType->getStringLength(), StringLen); 455 EXPECT_EQ(StringType->getStringLocationExp(), StringLocationExp); 456 457 StringRef StrNameExp = "stringexp"; 458 DIExpression *StringLengthExp = getDIExpression(2); 459 DIStringType *StringTypeExp = 460 DIB.createStringType(StrNameExp, StringLengthExp, StringLocationExp); 461 462 EXPECT_TRUE(isa_and_nonnull<DIStringType>(StringTypeExp)); 463 EXPECT_EQ(StringTypeExp->getName(), StrNameExp); 464 EXPECT_EQ(StringTypeExp->getStringLocationExp(), StringLocationExp); 465 EXPECT_EQ(StringTypeExp->getStringLengthExp(), StringLengthExp); 466 } 467 468 TEST(DIBuilder, DIEnumerator) { 469 LLVMContext Ctx; 470 std::unique_ptr<Module> M(new Module("MyModule", Ctx)); 471 DIBuilder DIB(*M); 472 APSInt I1(APInt(32, 1)); 473 APSInt I2(APInt(33, 1)); 474 475 auto *E = DIEnumerator::get(Ctx, I1, I1.isSigned(), "name"); 476 EXPECT_TRUE(E); 477 478 auto *E1 = DIEnumerator::getIfExists(Ctx, I1, I1.isSigned(), "name"); 479 EXPECT_TRUE(E1); 480 481 auto *E2 = DIEnumerator::getIfExists(Ctx, I2, I1.isSigned(), "name"); 482 EXPECT_FALSE(E2); 483 } 484 485 TEST(DbgAssignIntrinsicTest, replaceVariableLocationOp) { 486 LLVMContext C; 487 std::unique_ptr<Module> M = parseIR(C, R"( 488 define dso_local void @fun(i32 %v1, ptr %p1, ptr %p2) !dbg !7 { 489 entry: 490 call void @llvm.dbg.assign(metadata i32 %v1, metadata !14, metadata !DIExpression(), metadata !17, metadata ptr %p1, metadata !DIExpression()), !dbg !16 491 ret void 492 } 493 494 declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata) 495 496 !llvm.dbg.cu = !{!0} 497 !llvm.module.flags = !{!3} 498 499 !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) 500 !1 = !DIFile(filename: "test.cpp", directory: "/") 501 !3 = !{i32 2, !"Debug Info Version", i32 3} 502 !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) 503 !8 = !DISubroutineType(types: !9) 504 !9 = !{null} 505 !10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 506 !11 = !{} 507 !14 = !DILocalVariable(name: "Local", scope: !7, file: !1, line: 3, type: !10) 508 !16 = !DILocation(line: 0, scope: !7) 509 !17 = distinct !DIAssignID() 510 )"); 511 // Check the test IR isn't malformed. 512 ASSERT_TRUE(M); 513 514 Function &Fun = *M->getFunction("fun"); 515 Value *V1 = Fun.getArg(0); 516 Value *P1 = Fun.getArg(1); 517 Value *P2 = Fun.getArg(2); 518 DbgAssignIntrinsic *DAI = cast<DbgAssignIntrinsic>(Fun.begin()->begin()); 519 ASSERT_TRUE(V1 == DAI->getVariableLocationOp(0)); 520 ASSERT_TRUE(P1 == DAI->getAddress()); 521 522 #define TEST_REPLACE(Old, New, ExpectedValue, ExpectedAddr) \ 523 DAI->replaceVariableLocationOp(Old, New); \ 524 EXPECT_EQ(DAI->getVariableLocationOp(0), ExpectedValue); \ 525 EXPECT_EQ(DAI->getAddress(), ExpectedAddr); 526 527 // Replace address only. 528 TEST_REPLACE(/*Old*/ P1, /*New*/ P2, /*Value*/ V1, /*Address*/ P2); 529 // Replace value only. 530 TEST_REPLACE(/*Old*/ V1, /*New*/ P2, /*Value*/ P2, /*Address*/ P2); 531 // Replace both. 532 TEST_REPLACE(/*Old*/ P2, /*New*/ P1, /*Value*/ P1, /*Address*/ P1); 533 534 // Replace address only, value uses a DIArgList. 535 // Value = {DIArgList(V1)}, Addr = P1. 536 DAI->setRawLocation(DIArgList::get(C, ValueAsMetadata::get(V1))); 537 DAI->setExpression(DIExpression::get( 538 C, {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_stack_value})); 539 TEST_REPLACE(/*Old*/ P1, /*New*/ P2, /*Value*/ V1, /*Address*/ P2); 540 #undef TEST_REPLACE 541 } 542 543 TEST(AssignmentTrackingTest, Utils) { 544 // Test the assignment tracking utils defined in DebugInfo.h namespace at {}. 545 // This includes: 546 // getAssignmentInsts 547 // getAssignmentMarkers 548 // RAUW 549 // deleteAll 550 // 551 // The input IR includes two functions, fun1 and fun2. Both contain an alloca 552 // with a DIAssignID tag. fun1's alloca is linked to two llvm.dbg.assign 553 // intrinsics, one of which is for an inlined variable and appears before the 554 // alloca. 555 556 LLVMContext C; 557 std::unique_ptr<Module> M = parseIR(C, R"( 558 define dso_local void @fun1() !dbg !7 { 559 entry: 560 call void @llvm.dbg.assign(metadata i32 undef, metadata !10, metadata !DIExpression(), metadata !12, metadata i32 undef, metadata !DIExpression()), !dbg !13 561 %local = alloca i32, align 4, !DIAssignID !12 562 call void @llvm.dbg.assign(metadata i32 undef, metadata !16, metadata !DIExpression(), metadata !12, metadata i32 undef, metadata !DIExpression()), !dbg !15 563 ret void, !dbg !15 564 } 565 566 define dso_local void @fun2() !dbg !17 { 567 entry: 568 %local = alloca i32, align 4, !DIAssignID !20 569 call void @llvm.dbg.assign(metadata i32 undef, metadata !18, metadata !DIExpression(), metadata !20, metadata i32 undef, metadata !DIExpression()), !dbg !19 570 ret void, !dbg !19 571 } 572 573 define dso_local void @fun3() !dbg !21 { 574 entry: 575 %local = alloca i32, align 4, !DIAssignID !24 576 call void @llvm.dbg.assign(metadata i32 undef, metadata !22, metadata !DIExpression(), metadata !24, metadata i32* undef, metadata !DIExpression()), !dbg !23 577 ret void 578 } 579 580 declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata) 581 582 !llvm.dbg.cu = !{!0} 583 !llvm.module.flags = !{!3, !4, !5} 584 !llvm.ident = !{!6} 585 586 !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) 587 !1 = !DIFile(filename: "test.c", directory: "/") 588 !2 = !{} 589 !3 = !{i32 7, !"Dwarf Version", i32 4} 590 !4 = !{i32 2, !"Debug Info Version", i32 3} 591 !5 = !{i32 1, !"wchar_size", i32 4} 592 !6 = !{!"clang version 14.0.0"} 593 !7 = distinct !DISubprogram(name: "fun1", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) 594 !8 = !DISubroutineType(types: !9) 595 !9 = !{null} 596 !10 = !DILocalVariable(name: "local3", scope: !14, file: !1, line: 2, type: !11) 597 !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 598 !12 = distinct !DIAssignID() 599 !13 = !DILocation(line: 5, column: 1, scope: !14, inlinedAt: !15) 600 !14 = distinct !DISubprogram(name: "inline", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) 601 !15 = !DILocation(line: 3, column: 1, scope: !7) 602 !16 = !DILocalVariable(name: "local1", scope: !7, file: !1, line: 2, type: !11) 603 !17 = distinct !DISubprogram(name: "fun2", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) 604 !18 = !DILocalVariable(name: "local2", scope: !17, file: !1, line: 2, type: !11) 605 !19 = !DILocation(line: 4, column: 1, scope: !17) 606 !20 = distinct !DIAssignID() 607 !21 = distinct !DISubprogram(name: "fun3", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) 608 !22 = !DILocalVariable(name: "local4", scope: !21, file: !1, line: 2, type: !11) 609 !23 = !DILocation(line: 4, column: 1, scope: !21) 610 !24 = distinct !DIAssignID() 611 )"); 612 613 // Check the test IR isn't malformed. 614 ASSERT_TRUE(M); 615 616 Function &Fun1 = *M->getFunction("fun1"); 617 Instruction &Alloca = *Fun1.getEntryBlock().getFirstNonPHIOrDbg(); 618 619 // 1. Check the Instruction <-> Intrinsic mappings work in fun1. 620 // 621 // Check there are two llvm.dbg.assign intrinsics linked to Alloca. 622 auto CheckFun1Mapping = [&Alloca]() { 623 auto Markers = at::getAssignmentMarkers(&Alloca); 624 EXPECT_TRUE(std::distance(Markers.begin(), Markers.end()) == 2); 625 // Check those two entries are distinct. 626 DbgAssignIntrinsic *First = *Markers.begin(); 627 DbgAssignIntrinsic *Second = *std::next(Markers.begin()); 628 EXPECT_NE(First, Second); 629 630 // Check that we can get back to Alloca from each llvm.dbg.assign. 631 for (auto *DAI : Markers) { 632 auto Insts = at::getAssignmentInsts(DAI); 633 // Check there is exactly one instruction linked to each intrinsic. Use 634 // ASSERT_TRUE because we're going to dereference the begin iterator. 635 ASSERT_TRUE(std::distance(Insts.begin(), Insts.end()) == 1); 636 EXPECT_FALSE(Insts.empty()); 637 // Check the linked instruction is Alloca. 638 Instruction *LinkedInst = *Insts.begin(); 639 EXPECT_EQ(LinkedInst, &Alloca); 640 } 641 }; 642 CheckFun1Mapping(); 643 644 // 2. Check DIAssignID RAUW replaces attachments and uses. 645 // 646 DIAssignID *Old = 647 cast_or_null<DIAssignID>(Alloca.getMetadata(LLVMContext::MD_DIAssignID)); 648 DIAssignID *New = DIAssignID::getDistinct(C); 649 ASSERT_TRUE(Old && New && New != Old); 650 at::RAUW(Old, New); 651 // Check fun1's alloca and intrinsics have been updated and the mapping still 652 // works. 653 EXPECT_EQ(New, cast_or_null<DIAssignID>( 654 Alloca.getMetadata(LLVMContext::MD_DIAssignID))); 655 CheckFun1Mapping(); 656 657 // Check that fun2's alloca and intrinsic have not not been updated. 658 Instruction &Fun2Alloca = 659 *M->getFunction("fun2")->getEntryBlock().getFirstNonPHIOrDbg(); 660 DIAssignID *Fun2ID = cast_or_null<DIAssignID>( 661 Fun2Alloca.getMetadata(LLVMContext::MD_DIAssignID)); 662 EXPECT_NE(New, Fun2ID); 663 auto Fun2Markers = at::getAssignmentMarkers(&Fun2Alloca); 664 ASSERT_TRUE(std::distance(Fun2Markers.begin(), Fun2Markers.end()) == 1); 665 auto Fun2Insts = at::getAssignmentInsts(*Fun2Markers.begin()); 666 ASSERT_TRUE(std::distance(Fun2Insts.begin(), Fun2Insts.end()) == 1); 667 EXPECT_EQ(*Fun2Insts.begin(), &Fun2Alloca); 668 669 // 3. Check that deleting dbg.assigns from a specific instruction works. 670 Instruction &Fun3Alloca = 671 *M->getFunction("fun3")->getEntryBlock().getFirstNonPHIOrDbg(); 672 auto Fun3Markers = at::getAssignmentMarkers(&Fun3Alloca); 673 ASSERT_TRUE(std::distance(Fun3Markers.begin(), Fun3Markers.end()) == 1); 674 at::deleteAssignmentMarkers(&Fun3Alloca); 675 Fun3Markers = at::getAssignmentMarkers(&Fun3Alloca); 676 EXPECT_EQ(Fun3Markers.empty(), true); 677 678 // 4. Check that deleting works and applies only to the target function. 679 at::deleteAll(&Fun1); 680 // There should now only be the alloca and ret in fun1. 681 EXPECT_EQ(Fun1.begin()->size(), 2u); 682 // fun2's alloca should have the same DIAssignID and remain linked to its 683 // llvm.dbg.assign. 684 EXPECT_EQ(Fun2ID, cast_or_null<DIAssignID>( 685 Fun2Alloca.getMetadata(LLVMContext::MD_DIAssignID))); 686 EXPECT_FALSE(at::getAssignmentMarkers(&Fun2Alloca).empty()); 687 } 688 689 TEST(IRBuilder, GetSetInsertionPointWithEmptyBasicBlock) { 690 LLVMContext C; 691 std::unique_ptr<BasicBlock> BB(BasicBlock::Create(C, "start")); 692 Module *M = new Module("module", C); 693 IRBuilder<> Builder(BB.get()); 694 Function *DbgDeclare = Intrinsic::getDeclaration(M, Intrinsic::dbg_declare); 695 Value *DIV = MetadataAsValue::get(C, (Metadata *)nullptr); 696 SmallVector<Value *, 3> Args = {DIV, DIV, DIV}; 697 Builder.CreateCall(DbgDeclare, Args); 698 auto IP = BB->getFirstInsertionPt(); 699 Builder.SetInsertPoint(BB.get(), IP); 700 } 701 702 TEST(AssignmentTrackingTest, InstrMethods) { 703 // Test the assignment tracking Instruction methods. 704 // This includes: 705 // Instruction::mergeDIAssignID 706 707 LLVMContext C; 708 std::unique_ptr<Module> M = parseIR(C, R"( 709 define dso_local void @fun() #0 !dbg !8 { 710 entry: 711 %Local = alloca [2 x i32], align 4, !DIAssignID !12 712 call void @llvm.dbg.assign(metadata i1 undef, metadata !13, metadata !DIExpression(), metadata !12, metadata [2 x i32]* %Local, metadata !DIExpression()), !dbg !18 713 %arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* %Local, i64 0, i64 0, !dbg !19 714 store i32 5, i32* %arrayidx, align 4, !dbg !20, !DIAssignID !21 715 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 716 %arrayidx1 = getelementptr inbounds [2 x i32], [2 x i32]* %Local, i64 0, i64 1, !dbg !22 717 store i32 6, i32* %arrayidx1, align 4, !dbg !23, !DIAssignID !24 718 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 719 ret void, !dbg !25 720 } 721 722 declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata) #1 723 724 !llvm.dbg.cu = !{!0} 725 !llvm.module.flags = !{!2, !3, !4, !5, !6} 726 !llvm.ident = !{!7} 727 728 !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) 729 !1 = !DIFile(filename: "test.cpp", directory: "/") 730 !2 = !{i32 7, !"Dwarf Version", i32 5} 731 !3 = !{i32 2, !"Debug Info Version", i32 3} 732 !4 = !{i32 1, !"wchar_size", i32 4} 733 !5 = !{i32 7, !"uwtable", i32 1} 734 !6 = !{i32 7, !"frame-pointer", i32 2} 735 !7 = !{!"clang version 14.0.0"} 736 !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) 737 !9 = !DISubroutineType(types: !10) 738 !10 = !{null} 739 !11 = !{} 740 !12 = distinct !DIAssignID() 741 !13 = !DILocalVariable(name: "Local", scope: !8, file: !1, line: 2, type: !14) 742 !14 = !DICompositeType(tag: DW_TAG_array_type, baseType: !15, size: 64, elements: !16) 743 !15 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 744 !16 = !{!17} 745 !17 = !DISubrange(count: 2) 746 !18 = !DILocation(line: 0, scope: !8) 747 !19 = !DILocation(line: 3, column: 3, scope: !8) 748 !20 = !DILocation(line: 3, column: 12, scope: !8) 749 !21 = distinct !DIAssignID() 750 !22 = !DILocation(line: 4, column: 3, scope: !8) 751 !23 = !DILocation(line: 4, column: 12, scope: !8) 752 !24 = distinct !DIAssignID() 753 !25 = !DILocation(line: 5, column: 1, scope: !8) 754 )"); 755 756 // Check the test IR isn't malformed. 757 ASSERT_TRUE(M); 758 Function &Fun = *M->getFunction("fun"); 759 SmallVector<Instruction *> Stores; 760 for (auto &BB : Fun) { 761 for (auto &I : BB) { 762 if (isa<StoreInst>(&I)) 763 Stores.push_back(&I); 764 } 765 } 766 767 // The test requires (at least) 2 stores. 768 ASSERT_TRUE(Stores.size() == 2); 769 // Use SetVectors to check that the attachments and markers are unique 770 // (another test requirement). 771 SetVector<Metadata *> OrigIDs; 772 SetVector<DbgAssignIntrinsic *> Markers; 773 for (const Instruction *SI : Stores) { 774 Metadata *ID = SI->getMetadata(LLVMContext::MD_DIAssignID); 775 ASSERT_TRUE(OrigIDs.insert(ID)); 776 ASSERT_TRUE(ID != nullptr); 777 auto Range = at::getAssignmentMarkers(SI); 778 ASSERT_TRUE(std::distance(Range.begin(), Range.end()) == 1); 779 ASSERT_TRUE(Markers.insert(*Range.begin())); 780 } 781 782 // Test 1 - mergeDIAssignID. 783 // 784 // Input store0->mergeDIAssignID(store1) 785 // ----- ------------------------- 786 // store0 !x store0 !x 787 // dbg.assign0 !x dbg.assign !x 788 // store1 !y store1 !x 789 // dbg.assign1 !y dbg.assign1 !x 790 { 791 Stores[0]->mergeDIAssignID(Stores[1]); 792 // Check that the stores share the same ID. 793 Metadata *NewID0 = Stores[0]->getMetadata(LLVMContext::MD_DIAssignID); 794 Metadata *NewID1 = Stores[1]->getMetadata(LLVMContext::MD_DIAssignID); 795 EXPECT_NE(NewID0, nullptr); 796 EXPECT_EQ(NewID0, NewID1); 797 EXPECT_EQ(Markers[0]->getAssignID(), NewID0); 798 EXPECT_EQ(Markers[1]->getAssignID(), NewID0); 799 } 800 801 // Test 2 - mergeDIAssignID. 802 // 803 // Input store0->mergeDIAssignID(store1) 804 // ----- ------------------------- 805 // store0 !x store0 !x 806 // dbg.assign0 !x dbg.assign !x 807 // store1 store1 808 { 809 Stores[1]->setMetadata(LLVMContext::MD_DIAssignID, nullptr); 810 Stores[0]->mergeDIAssignID(Stores[1]); 811 // Check that store1 doesn't get a new ID. 812 Metadata *NewID0 = Stores[0]->getMetadata(LLVMContext::MD_DIAssignID); 813 Metadata *NewID1 = Stores[1]->getMetadata(LLVMContext::MD_DIAssignID); 814 EXPECT_NE(NewID0, nullptr); 815 EXPECT_EQ(NewID1, nullptr); 816 EXPECT_EQ(Markers[0]->getAssignID(), NewID0); 817 } 818 819 // Test 3 - mergeDIAssignID. 820 // 821 // Input store1->mergeDIAssignID(store0) 822 // ----- ------------------------- 823 // store0 !x store0 !x 824 // dbg.assign0 !x dbg.assign !x 825 // store1 store1 !x 826 { 827 Stores[1]->setMetadata(LLVMContext::MD_DIAssignID, nullptr); 828 Stores[1]->mergeDIAssignID(Stores[0]); 829 // Check that the stores share the same ID (note store1 starts with none). 830 Metadata *NewID0 = Stores[0]->getMetadata(LLVMContext::MD_DIAssignID); 831 Metadata *NewID1 = Stores[1]->getMetadata(LLVMContext::MD_DIAssignID); 832 EXPECT_NE(NewID0, nullptr); 833 EXPECT_EQ(NewID0, NewID1); 834 EXPECT_EQ(Markers[0]->getAssignID(), NewID0); 835 } 836 837 // Test 4 - mergeDIAssignID. 838 // 839 // Input store1->mergeDIAssignID(store0) 840 // ----- ------------------------- 841 // store0 !x store0 !x 842 // dbg.assign0 !x dbg.assign !x 843 // store1 !x store1 !x 844 { 845 Stores[0]->mergeDIAssignID(Stores[1]); 846 // Check that the stores share the same ID. 847 Metadata *NewID0 = Stores[0]->getMetadata(LLVMContext::MD_DIAssignID); 848 Metadata *NewID1 = Stores[1]->getMetadata(LLVMContext::MD_DIAssignID); 849 EXPECT_NE(NewID0, nullptr); 850 EXPECT_EQ(NewID0, NewID1); 851 EXPECT_EQ(Markers[0]->getAssignID(), NewID0); 852 } 853 854 // Test 5 - dropUnknownNonDebugMetadata. 855 // 856 // Input store0->dropUnknownNonDebugMetadata() 857 // ----- ------------------------- 858 // store0 !x store0 !x 859 { 860 Stores[0]->dropUnknownNonDebugMetadata(); 861 Metadata *NewID0 = Stores[0]->getMetadata(LLVMContext::MD_DIAssignID); 862 EXPECT_NE(NewID0, nullptr); 863 } 864 } 865 866 // Test some very straight-forward operations on DbgVariableRecords -- these are 867 // dbg.values that have been converted to a non-instruction format. 868 TEST(MetadataTest, ConvertDbgToDbgVariableRecord) { 869 LLVMContext C; 870 std::unique_ptr<Module> M = parseIR(C, R"( 871 define i16 @f(i16 %a) !dbg !6 { 872 call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 873 %b = add i16 %a, 1, !dbg !11 874 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 875 ret i16 0, !dbg !11 876 877 exit: 878 %c = add i16 %b, 1, !dbg !11 879 ret i16 0, !dbg !11 880 } 881 declare void @llvm.dbg.value(metadata, metadata, metadata) #0 882 attributes #0 = { nounwind readnone speculatable willreturn } 883 884 !llvm.dbg.cu = !{!0} 885 !llvm.module.flags = !{!5} 886 887 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 888 !1 = !DIFile(filename: "t.ll", directory: "/") 889 !2 = !{} 890 !5 = !{i32 2, !"Debug Info Version", i32 3} 891 !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8) 892 !7 = !DISubroutineType(types: !2) 893 !8 = !{!9} 894 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) 895 !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned) 896 !11 = !DILocation(line: 1, column: 1, scope: !6) 897 )"); 898 899 // Find the first dbg.value, 900 Instruction &I = *M->getFunction("f")->getEntryBlock().getFirstNonPHI(); 901 const DILocalVariable *Var = nullptr; 902 const DIExpression *Expr = nullptr; 903 const DILocation *Loc = nullptr; 904 const Metadata *MLoc = nullptr; 905 DbgVariableRecord *DVR1 = nullptr; 906 { 907 DbgValueInst *DPI = dyn_cast<DbgValueInst>(&I); 908 ASSERT_TRUE(DPI); 909 Var = DPI->getVariable(); 910 Expr = DPI->getExpression(); 911 Loc = DPI->getDebugLoc().get(); 912 MLoc = DPI->getRawLocation(); 913 914 // Test the creation of a DbgVariableRecord and it's conversion back to a 915 // dbg.value. 916 DVR1 = new DbgVariableRecord(DPI); 917 EXPECT_EQ(DVR1->getVariable(), Var); 918 EXPECT_EQ(DVR1->getExpression(), Expr); 919 EXPECT_EQ(DVR1->getDebugLoc().get(), Loc); 920 EXPECT_EQ(DVR1->getRawLocation(), MLoc); 921 922 // Erase dbg.value, 923 DPI->eraseFromParent(); 924 // Re-create from DVR1, inserting at front. 925 DVR1->createDebugIntrinsic(&*M, 926 &M->getFunction("f")->getEntryBlock().front()); 927 928 Instruction *NewDPI = &M->getFunction("f")->getEntryBlock().front(); 929 DbgValueInst *DPI2 = dyn_cast<DbgValueInst>(NewDPI); 930 ASSERT_TRUE(DPI2); 931 EXPECT_EQ(DPI2->getVariable(), Var); 932 EXPECT_EQ(DPI2->getExpression(), Expr); 933 EXPECT_EQ(DPI2->getDebugLoc().get(), Loc); 934 EXPECT_EQ(DPI2->getRawLocation(), MLoc); 935 } 936 937 // Fetch the second dbg.value, convert it to a DbgVariableRecord, 938 BasicBlock::iterator It = M->getFunction("f")->getEntryBlock().begin(); 939 It = std::next(std::next(It)); 940 DbgValueInst *DPI3 = dyn_cast<DbgValueInst>(It); 941 ASSERT_TRUE(DPI3); 942 DbgVariableRecord *DVR2 = new DbgVariableRecord(DPI3); 943 944 // These dbg.values are supposed to refer to different values. 945 EXPECT_NE(DVR1->getRawLocation(), DVR2->getRawLocation()); 946 947 // Try manipulating DbgVariableRecords and markers in the exit block. 948 BasicBlock *ExitBlock = &*std::next(M->getFunction("f")->getEntryBlock().getIterator()); 949 Instruction *FirstInst = &ExitBlock->front(); 950 Instruction *RetInst = &*std::next(FirstInst->getIterator()); 951 952 // Set-up DbgMarkers in this block. 953 ExitBlock->IsNewDbgInfoFormat = true; 954 ExitBlock->createMarker(FirstInst); 955 ExitBlock->createMarker(RetInst); 956 957 // Insert DbgRecords into markers, order should come out DVR2, DVR1. 958 FirstInst->DebugMarker->insertDbgRecord(DVR1, false); 959 FirstInst->DebugMarker->insertDbgRecord(DVR2, true); 960 unsigned int ItCount = 0; 961 for (DbgRecord &Item : FirstInst->DebugMarker->getDbgRecordRange()) { 962 EXPECT_TRUE((&Item == DVR2 && ItCount == 0) || 963 (&Item == DVR1 && ItCount == 1)); 964 EXPECT_EQ(Item.getMarker(), FirstInst->DebugMarker); 965 ++ItCount; 966 } 967 968 // Clone them onto the second marker -- should allocate new DVRs. 969 RetInst->DebugMarker->cloneDebugInfoFrom(FirstInst->DebugMarker, std::nullopt, 970 false); 971 EXPECT_EQ(RetInst->DebugMarker->StoredDbgRecords.size(), 2u); 972 ItCount = 0; 973 // Check these things store the same information; but that they're not the same 974 // objects. 975 for (DbgVariableRecord &Item : 976 filterDbgVars(RetInst->DebugMarker->getDbgRecordRange())) { 977 EXPECT_TRUE( 978 (Item.getRawLocation() == DVR2->getRawLocation() && ItCount == 0) || 979 (Item.getRawLocation() == DVR1->getRawLocation() && ItCount == 1)); 980 981 EXPECT_EQ(Item.getMarker(), RetInst->DebugMarker); 982 EXPECT_NE(&Item, DVR1); 983 EXPECT_NE(&Item, DVR2); 984 ++ItCount; 985 } 986 987 RetInst->DebugMarker->dropDbgRecords(); 988 EXPECT_EQ(RetInst->DebugMarker->StoredDbgRecords.size(), 0u); 989 990 // Try cloning one single DbgVariableRecord. 991 auto DIIt = std::next(FirstInst->DebugMarker->getDbgRecordRange().begin()); 992 RetInst->DebugMarker->cloneDebugInfoFrom(FirstInst->DebugMarker, DIIt, false); 993 EXPECT_EQ(RetInst->DebugMarker->StoredDbgRecords.size(), 1u); 994 // The second DbgVariableRecord should have been cloned; it should have the 995 // same values as DVR1. 996 EXPECT_EQ( 997 cast<DbgVariableRecord>(RetInst->DebugMarker->StoredDbgRecords.begin()) 998 ->getRawLocation(), 999 DVR1->getRawLocation()); 1000 // We should be able to drop individual DbgRecords. 1001 RetInst->DebugMarker->dropOneDbgRecord( 1002 &*RetInst->DebugMarker->StoredDbgRecords.begin()); 1003 1004 // "Aborb" a DbgMarker: this means pretend that the instruction it's attached 1005 // to is disappearing so it needs to be transferred into "this" marker. 1006 RetInst->DebugMarker->absorbDebugValues(*FirstInst->DebugMarker, true); 1007 EXPECT_EQ(RetInst->DebugMarker->StoredDbgRecords.size(), 2u); 1008 // Should be the DVR1 and DVR2 objects. 1009 ItCount = 0; 1010 for (DbgRecord &Item : RetInst->DebugMarker->getDbgRecordRange()) { 1011 EXPECT_TRUE((&Item == DVR2 && ItCount == 0) || 1012 (&Item == DVR1 && ItCount == 1)); 1013 EXPECT_EQ(Item.getMarker(), RetInst->DebugMarker); 1014 ++ItCount; 1015 } 1016 1017 // Finally -- there are two DbgVariableRecords left over. If we remove 1018 // evrything in the basic block, then they should sink down into the 1019 // "TrailingDbgRecords" container for dangling debug-info. Future facilities 1020 // will restore them back when a terminator is inserted. 1021 FirstInst->DebugMarker->removeMarker(); 1022 FirstInst->eraseFromParent(); 1023 RetInst->DebugMarker->removeMarker(); 1024 RetInst->eraseFromParent(); 1025 1026 DbgMarker *EndMarker = ExitBlock->getTrailingDbgRecords(); 1027 ASSERT_NE(EndMarker, nullptr); 1028 EXPECT_EQ(EndMarker->StoredDbgRecords.size(), 2u); 1029 // Test again that it's those two DbgVariableRecords, DVR1 and DVR2. 1030 ItCount = 0; 1031 for (DbgRecord &Item : EndMarker->getDbgRecordRange()) { 1032 EXPECT_TRUE((&Item == DVR2 && ItCount == 0) || 1033 (&Item == DVR1 && ItCount == 1)); 1034 EXPECT_EQ(Item.getMarker(), EndMarker); 1035 ++ItCount; 1036 } 1037 1038 // Cleanup the trailing DbgVariableRecord records and marker. 1039 EndMarker->eraseFromParent(); 1040 1041 // The record of those trailing DbgVariableRecords would dangle and cause an 1042 // assertion failure if it lived until the end of the LLVMContext. 1043 ExitBlock->deleteTrailingDbgRecords(); 1044 } 1045 1046 TEST(MetadataTest, DbgVariableRecordConversionRoutines) { 1047 LLVMContext C; 1048 1049 // For the purpose of this test, set and un-set the command line option 1050 // corresponding to UseNewDbgInfoFormat. 1051 UseNewDbgInfoFormat = true; 1052 1053 std::unique_ptr<Module> M = parseIR(C, R"( 1054 define i16 @f(i16 %a) !dbg !6 { 1055 call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 1056 %b = add i16 %a, 1, !dbg !11 1057 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 1058 ret i16 0, !dbg !11 1059 1060 exit: 1061 %c = add i16 %b, 1, !dbg !11 1062 ret i16 0, !dbg !11 1063 } 1064 declare void @llvm.dbg.value(metadata, metadata, metadata) #0 1065 attributes #0 = { nounwind readnone speculatable willreturn } 1066 1067 !llvm.dbg.cu = !{!0} 1068 !llvm.module.flags = !{!5} 1069 1070 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 1071 !1 = !DIFile(filename: "t.ll", directory: "/") 1072 !2 = !{} 1073 !5 = !{i32 2, !"Debug Info Version", i32 3} 1074 !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8) 1075 !7 = !DISubroutineType(types: !2) 1076 !8 = !{!9} 1077 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) 1078 !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned) 1079 !11 = !DILocation(line: 1, column: 1, scope: !6) 1080 )"); 1081 1082 // Check that the conversion routines and utilities between dbg.value 1083 // debug-info format and DbgVariableRecords works. 1084 Function *F = M->getFunction("f"); 1085 BasicBlock *BB1 = &F->getEntryBlock(); 1086 // First instruction should be a dbg.value. 1087 EXPECT_TRUE(isa<DbgValueInst>(BB1->front())); 1088 EXPECT_FALSE(BB1->IsNewDbgInfoFormat); 1089 // Validating the block for DbgVariableRecords / DbgMarkers shouldn't fail -- 1090 // there's no data stored right now. 1091 bool BrokenDebugInfo = false; 1092 bool Error = verifyModule(*M, &errs(), &BrokenDebugInfo); 1093 EXPECT_FALSE(Error); 1094 EXPECT_FALSE(BrokenDebugInfo); 1095 1096 // Function and module should be marked as not having the new format too. 1097 EXPECT_FALSE(F->IsNewDbgInfoFormat); 1098 EXPECT_FALSE(M->IsNewDbgInfoFormat); 1099 1100 // Now convert. 1101 M->convertToNewDbgValues(); 1102 EXPECT_TRUE(M->IsNewDbgInfoFormat); 1103 EXPECT_TRUE(F->IsNewDbgInfoFormat); 1104 EXPECT_TRUE(BB1->IsNewDbgInfoFormat); 1105 1106 // There should now be no dbg.value instructions! 1107 // Ensure the first instruction exists, the test all of them. 1108 EXPECT_FALSE(isa<DbgValueInst>(BB1->front())); 1109 for (auto &BB : *F) 1110 for (auto &I : BB) 1111 EXPECT_FALSE(isa<DbgValueInst>(I)); 1112 1113 // There should be a DbgMarker on each of the two instructions in the entry 1114 // block, each containing one DbgVariableRecord. 1115 EXPECT_EQ(BB1->size(), 2u); 1116 Instruction *FirstInst = &BB1->front(); 1117 Instruction *SecondInst = FirstInst->getNextNode(); 1118 ASSERT_TRUE(FirstInst->DebugMarker); 1119 ASSERT_TRUE(SecondInst->DebugMarker); 1120 EXPECT_NE(FirstInst->DebugMarker, SecondInst->DebugMarker); 1121 EXPECT_EQ(FirstInst, FirstInst->DebugMarker->MarkedInstr); 1122 EXPECT_EQ(SecondInst, SecondInst->DebugMarker->MarkedInstr); 1123 1124 EXPECT_EQ(FirstInst->DebugMarker->StoredDbgRecords.size(), 1u); 1125 DbgVariableRecord *DVR1 = cast<DbgVariableRecord>( 1126 &*FirstInst->DebugMarker->getDbgRecordRange().begin()); 1127 EXPECT_EQ(DVR1->getMarker(), FirstInst->DebugMarker); 1128 // Should point at %a, an argument. 1129 EXPECT_TRUE(isa<Argument>(DVR1->getVariableLocationOp(0))); 1130 1131 EXPECT_EQ(SecondInst->DebugMarker->StoredDbgRecords.size(), 1u); 1132 DbgVariableRecord *DVR2 = cast<DbgVariableRecord>( 1133 &*SecondInst->DebugMarker->getDbgRecordRange().begin()); 1134 EXPECT_EQ(DVR2->getMarker(), SecondInst->DebugMarker); 1135 // Should point at FirstInst. 1136 EXPECT_EQ(DVR2->getVariableLocationOp(0), FirstInst); 1137 1138 // There should be no DbgVariableRecords / DbgMarkers in the second block, but 1139 // it should be marked as being in the new format. 1140 BasicBlock *BB2 = BB1->getNextNode(); 1141 EXPECT_TRUE(BB2->IsNewDbgInfoFormat); 1142 for (auto &Inst : *BB2) 1143 // Either there should be no marker, or it should be empty. 1144 EXPECT_TRUE(!Inst.DebugMarker || 1145 Inst.DebugMarker->StoredDbgRecords.empty()); 1146 1147 // Validating the first block should continue to not be a problem, 1148 Error = verifyModule(*M, &errs(), &BrokenDebugInfo); 1149 EXPECT_FALSE(Error); 1150 EXPECT_FALSE(BrokenDebugInfo); 1151 // But if we were to break something, it should be able to fire. Don't attempt 1152 // to comprehensively test the validator, it's a smoke-test rather than a 1153 // "proper" verification pass. 1154 DVR1->setMarker(nullptr); 1155 // A marker pointing the wrong way should be an error. 1156 Error = verifyModule(*M, &errs(), &BrokenDebugInfo); 1157 EXPECT_FALSE(Error); 1158 EXPECT_TRUE(BrokenDebugInfo); 1159 DVR1->setMarker(FirstInst->DebugMarker); 1160 1161 DILocalVariable *DLV1 = DVR1->getVariable(); 1162 DIExpression *Expr1 = DVR1->getExpression(); 1163 DILocalVariable *DLV2 = DVR2->getVariable(); 1164 DIExpression *Expr2 = DVR2->getExpression(); 1165 1166 // Convert everything back to the "old" format and ensure it's right. 1167 M->convertFromNewDbgValues(); 1168 EXPECT_FALSE(M->IsNewDbgInfoFormat); 1169 EXPECT_FALSE(F->IsNewDbgInfoFormat); 1170 EXPECT_FALSE(BB1->IsNewDbgInfoFormat); 1171 1172 EXPECT_EQ(BB1->size(), 4u); 1173 ASSERT_TRUE(isa<DbgValueInst>(BB1->front())); 1174 DbgValueInst *DVI1 = cast<DbgValueInst>(&BB1->front()); 1175 // These dbg.values should still point at the same places. 1176 EXPECT_TRUE(isa<Argument>(DVI1->getVariableLocationOp(0))); 1177 DbgValueInst *DVI2 = cast<DbgValueInst>(DVI1->getNextNode()->getNextNode()); 1178 EXPECT_EQ(DVI2->getVariableLocationOp(0), FirstInst); 1179 1180 // Check a few fields too, 1181 EXPECT_EQ(DVI1->getVariable(), DLV1); 1182 EXPECT_EQ(DVI1->getExpression(), Expr1); 1183 EXPECT_EQ(DVI2->getVariable(), DLV2); 1184 EXPECT_EQ(DVI2->getExpression(), Expr2); 1185 1186 UseNewDbgInfoFormat = false; 1187 } 1188 1189 // Test that the hashing function for DISubprograms produce the same result 1190 // after replacing the temporary scope. 1191 TEST(DIBuilder, HashingDISubprogram) { 1192 LLVMContext Ctx; 1193 std::unique_ptr<Module> M = std::make_unique<Module>("MyModule", Ctx); 1194 DIBuilder DIB(*M); 1195 1196 DIFile *F = DIB.createFile("main.c", "/"); 1197 DICompileUnit *CU = 1198 DIB.createCompileUnit(dwarf::DW_LANG_C, F, "Test", false, "", 0); 1199 1200 llvm::TempDIType ForwardDeclaredType = 1201 llvm::TempDIType(DIB.createReplaceableCompositeType( 1202 llvm::dwarf::DW_TAG_structure_type, "MyType", CU, F, 0, 0, 8, 8, {}, 1203 "UniqueIdentifier")); 1204 1205 // The hashing function is different for declarations and definitions, so 1206 // create one of each. 1207 DISubprogram *Declaration = 1208 DIB.createMethod(ForwardDeclaredType.get(), "MethodName", "LinkageName", 1209 F, 0, DIB.createSubroutineType({})); 1210 1211 DISubprogram *Definition = DIB.createFunction( 1212 ForwardDeclaredType.get(), "MethodName", "LinkageName", F, 0, 1213 DIB.createSubroutineType({}), 0, DINode::FlagZero, 1214 llvm::DISubprogram::SPFlagDefinition, nullptr, Declaration); 1215 1216 // Produce the hash with the temporary scope. 1217 unsigned HashDeclaration = 1218 MDNodeKeyImpl<DISubprogram>(Declaration).getHashValue(); 1219 unsigned HashDefinition = 1220 MDNodeKeyImpl<DISubprogram>(Definition).getHashValue(); 1221 1222 // Instantiate the real scope and replace the temporary one with it. 1223 DICompositeType *Type = DIB.createStructType(CU, "MyType", F, 0, 8, 8, {}, {}, 1224 {}, 0, {}, "UniqueIdentifier"); 1225 DIB.replaceTemporary(std::move(ForwardDeclaredType), Type); 1226 1227 // Now make sure the hashing is consistent. 1228 unsigned HashDeclarationAfter = 1229 MDNodeKeyImpl<DISubprogram>(Declaration).getHashValue(); 1230 unsigned HashDefinitionAfter = 1231 MDNodeKeyImpl<DISubprogram>(Definition).getHashValue(); 1232 1233 EXPECT_EQ(HashDeclaration, HashDeclarationAfter); 1234 EXPECT_EQ(HashDefinition, HashDefinitionAfter); 1235 } 1236 1237 } // end namespace 1238