1 //===- llvm/unittest/IR/BasicBlockTest.cpp - BasicBlock unit 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/BasicBlock.h" 10 #include "llvm/IR/DebugInfo.h" 11 #include "llvm/ADT/STLExtras.h" 12 #include "llvm/AsmParser/Parser.h" 13 #include "llvm/IR/Function.h" 14 #include "llvm/IR/IRBuilder.h" 15 #include "llvm/IR/Instruction.h" 16 #include "llvm/IR/Instructions.h" 17 #include "llvm/IR/LLVMContext.h" 18 #include "llvm/IR/Module.h" 19 #include "llvm/IR/NoFolder.h" 20 #include "llvm/IR/Verifier.h" 21 #include "llvm/Support/SourceMgr.h" 22 #include "gmock/gmock-matchers.h" 23 #include "gtest/gtest.h" 24 #include <memory> 25 26 using namespace llvm; 27 28 extern cl::opt<bool> UseNewDbgInfoFormat; 29 30 static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) { 31 SMDiagnostic Err; 32 std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C); 33 if (!Mod) 34 Err.print("BasicBlockDbgInfoTest", errs()); 35 return Mod; 36 } 37 38 namespace { 39 40 // We can occasionally moveAfter an instruction so that it moves to the 41 // position that it already resides at. This is fine -- but gets complicated 42 // with dbg.value intrinsics. By moving an instruction, we can end up changing 43 // nothing but the location of debug-info intrinsics. That has to be modelled 44 // by DbgVariableRecords, the dbg.value replacement. 45 TEST(BasicBlockDbgInfoTest, InsertAfterSelf) { 46 LLVMContext C; 47 UseNewDbgInfoFormat = true; 48 49 std::unique_ptr<Module> M = parseIR(C, R"( 50 define i16 @f(i16 %a) !dbg !6 { 51 call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 52 %b = add i16 %a, 1, !dbg !11 53 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 54 %c = add i16 %b, 1, !dbg !11 55 ret i16 0, !dbg !11 56 } 57 declare void @llvm.dbg.value(metadata, metadata, metadata) #0 58 attributes #0 = { nounwind readnone speculatable willreturn } 59 60 !llvm.dbg.cu = !{!0} 61 !llvm.module.flags = !{!5} 62 63 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 64 !1 = !DIFile(filename: "t.ll", directory: "/") 65 !2 = !{} 66 !5 = !{i32 2, !"Debug Info Version", i32 3} 67 !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8) 68 !7 = !DISubroutineType(types: !2) 69 !8 = !{!9} 70 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) 71 !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned) 72 !11 = !DILocation(line: 1, column: 1, scope: !6) 73 )"); 74 75 // Convert the module to "new" form debug-info. 76 M->convertToNewDbgValues(); 77 // Fetch the entry block. 78 BasicBlock &BB = M->getFunction("f")->getEntryBlock(); 79 80 Instruction *Inst1 = &*BB.begin(); 81 Instruction *Inst2 = &*std::next(BB.begin()); 82 Instruction *RetInst = &*std::next(Inst2->getIterator()); 83 EXPECT_TRUE(Inst1->hasDbgRecords()); 84 EXPECT_TRUE(Inst2->hasDbgRecords()); 85 EXPECT_FALSE(RetInst->hasDbgRecords()); 86 87 // If we move Inst2 to be after Inst1, then it comes _immediately_ after. Were 88 // we in dbg.value form we would then have: 89 // dbg.value 90 // %b = add 91 // %c = add 92 // dbg.value 93 // Check that this is replicated by DbgVariableRecords. 94 Inst2->moveAfter(Inst1); 95 96 // Inst1 should only have one DbgVariableRecord on it. 97 EXPECT_TRUE(Inst1->hasDbgRecords()); 98 auto Range1 = Inst1->getDbgRecordRange(); 99 EXPECT_EQ(std::distance(Range1.begin(), Range1.end()), 1u); 100 // Inst2 should have none. 101 EXPECT_FALSE(Inst2->hasDbgRecords()); 102 // While the return inst should now have one on it. 103 EXPECT_TRUE(RetInst->hasDbgRecords()); 104 auto Range2 = RetInst->getDbgRecordRange(); 105 EXPECT_EQ(std::distance(Range2.begin(), Range2.end()), 1u); 106 107 M->convertFromNewDbgValues(); 108 109 UseNewDbgInfoFormat = false; 110 } 111 112 TEST(BasicBlockDbgInfoTest, SplitBasicBlockBefore) { 113 LLVMContext C; 114 UseNewDbgInfoFormat = true; 115 116 std::unique_ptr<Module> M = parseIR(C, R"---( 117 define dso_local void @func() #0 !dbg !10 { 118 %1 = alloca i32, align 4 119 tail call void @llvm.dbg.declare(metadata ptr %1, metadata !14, metadata !DIExpression()), !dbg !16 120 store i32 2, ptr %1, align 4, !dbg !16 121 ret void, !dbg !17 122 } 123 124 declare void @llvm.dbg.declare(metadata, metadata, metadata) #0 125 126 attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } 127 128 !llvm.dbg.cu = !{!0} 129 !llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8} 130 !llvm.ident = !{!9} 131 132 !0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "dummy", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) 133 !1 = !DIFile(filename: "dummy", directory: "dummy") 134 !2 = !{i32 7, !"Dwarf Version", i32 5} 135 !3 = !{i32 2, !"Debug Info Version", i32 3} 136 !4 = !{i32 1, !"wchar_size", i32 4} 137 !5 = !{i32 8, !"PIC Level", i32 2} 138 !6 = !{i32 7, !"PIE Level", i32 2} 139 !7 = !{i32 7, !"uwtable", i32 2} 140 !8 = !{i32 7, !"frame-pointer", i32 2} 141 !9 = !{!"dummy"} 142 !10 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !13) 143 !11 = !DISubroutineType(types: !12) 144 !12 = !{null} 145 !13 = !{} 146 !14 = !DILocalVariable(name: "a", scope: !10, file: !1, line: 2, type: !15) 147 !15 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 148 !16 = !DILocation(line: 2, column: 6, scope: !10) 149 !17 = !DILocation(line: 3, column: 2, scope: !10) 150 )---"); 151 ASSERT_TRUE(M); 152 153 M->convertToNewDbgValues(); 154 155 Function *F = M->getFunction("func"); 156 157 BasicBlock &BB = F->getEntryBlock(); 158 auto I = std::prev(BB.end(), 2); 159 BB.splitBasicBlockBefore(I, "before"); 160 161 BasicBlock &BBBefore = F->getEntryBlock(); 162 auto I2 = std::prev(BBBefore.end(), 2); 163 ASSERT_TRUE(I2->hasDbgRecords()); 164 165 UseNewDbgInfoFormat = false; 166 } 167 168 TEST(BasicBlockDbgInfoTest, MarkerOperations) { 169 LLVMContext C; 170 UseNewDbgInfoFormat = true; 171 172 std::unique_ptr<Module> M = parseIR(C, R"( 173 define i16 @f(i16 %a) !dbg !6 { 174 call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 175 %b = add i16 %a, 1, !dbg !11 176 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 177 ret i16 0, !dbg !11 178 } 179 declare void @llvm.dbg.value(metadata, metadata, metadata) #0 180 attributes #0 = { nounwind readnone speculatable willreturn } 181 182 !llvm.dbg.cu = !{!0} 183 !llvm.module.flags = !{!5} 184 185 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 186 !1 = !DIFile(filename: "t.ll", directory: "/") 187 !2 = !{} 188 !5 = !{i32 2, !"Debug Info Version", i32 3} 189 !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8) 190 !7 = !DISubroutineType(types: !2) 191 !8 = !{!9} 192 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) 193 !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned) 194 !11 = !DILocation(line: 1, column: 1, scope: !6) 195 )"); 196 197 // Fetch the entry block, 198 BasicBlock &BB = M->getFunction("f")->getEntryBlock(); 199 // Convert the module to "new" form debug-info. 200 M->convertToNewDbgValues(); 201 EXPECT_EQ(BB.size(), 2u); 202 203 // Fetch out our two markers, 204 Instruction *Instr1 = &*BB.begin(); 205 Instruction *Instr2 = Instr1->getNextNode(); 206 DbgMarker *Marker1 = Instr1->DebugMarker; 207 DbgMarker *Marker2 = Instr2->DebugMarker; 208 // There's no TrailingDbgRecords marker allocated yet. 209 DbgMarker *EndMarker = nullptr; 210 211 // Check that the "getMarker" utilities operate as expected. 212 EXPECT_EQ(BB.getMarker(Instr1->getIterator()), Marker1); 213 EXPECT_EQ(BB.getMarker(Instr2->getIterator()), Marker2); 214 EXPECT_EQ(BB.getNextMarker(Instr1), Marker2); 215 EXPECT_EQ(BB.getNextMarker(Instr2), EndMarker); // Is nullptr. 216 217 // There should be two DbgVariableRecords, 218 EXPECT_EQ(Marker1->StoredDbgRecords.size(), 1u); 219 EXPECT_EQ(Marker2->StoredDbgRecords.size(), 1u); 220 221 // Unlink them and try to re-insert them through the basic block. 222 DbgRecord *DVR1 = &*Marker1->StoredDbgRecords.begin(); 223 DbgRecord *DVR2 = &*Marker2->StoredDbgRecords.begin(); 224 DVR1->removeFromParent(); 225 DVR2->removeFromParent(); 226 EXPECT_TRUE(Marker1->StoredDbgRecords.empty()); 227 EXPECT_TRUE(Marker2->StoredDbgRecords.empty()); 228 229 // This should appear in Marker1. 230 BB.insertDbgRecordBefore(DVR1, BB.begin()); 231 EXPECT_EQ(Marker1->StoredDbgRecords.size(), 1u); 232 EXPECT_EQ(DVR1, &*Marker1->StoredDbgRecords.begin()); 233 234 // This should attach to Marker2. 235 BB.insertDbgRecordAfter(DVR2, &*BB.begin()); 236 EXPECT_EQ(Marker2->StoredDbgRecords.size(), 1u); 237 EXPECT_EQ(DVR2, &*Marker2->StoredDbgRecords.begin()); 238 239 // Now, how about removing instructions? That should cause any 240 // DbgVariableRecords to "fall down". 241 Instr1->removeFromParent(); 242 Marker1 = nullptr; 243 // DbgVariableRecords should now be in Marker2. 244 EXPECT_EQ(BB.size(), 1u); 245 EXPECT_EQ(Marker2->StoredDbgRecords.size(), 2u); 246 // They should also be in the correct order. 247 SmallVector<DbgRecord *, 2> DVRs; 248 for (DbgRecord &DVR : Marker2->getDbgRecordRange()) 249 DVRs.push_back(&DVR); 250 EXPECT_EQ(DVRs[0], DVR1); 251 EXPECT_EQ(DVRs[1], DVR2); 252 253 // If we remove the end instruction, the DbgVariableRecords should fall down 254 // into the trailing marker. 255 EXPECT_EQ(BB.getTrailingDbgRecords(), nullptr); 256 Instr2->removeFromParent(); 257 EXPECT_TRUE(BB.empty()); 258 EndMarker = BB.getTrailingDbgRecords(); 259 ASSERT_NE(EndMarker, nullptr); 260 EXPECT_EQ(EndMarker->StoredDbgRecords.size(), 2u); 261 // Again, these should arrive in the correct order. 262 263 DVRs.clear(); 264 for (DbgRecord &DVR : EndMarker->getDbgRecordRange()) 265 DVRs.push_back(&DVR); 266 EXPECT_EQ(DVRs[0], DVR1); 267 EXPECT_EQ(DVRs[1], DVR2); 268 269 // Inserting a normal instruction at the beginning: shouldn't dislodge the 270 // DbgVariableRecords. It's intended to not go at the start. 271 Instr1->insertBefore(BB, BB.begin()); 272 EXPECT_EQ(EndMarker->StoredDbgRecords.size(), 2u); 273 Instr1->removeFromParent(); 274 275 // Inserting at end(): should dislodge the DbgVariableRecords, if they were 276 // dbg.values then they would sit "above" the new instruction. 277 Instr1->insertBefore(BB, BB.end()); 278 EXPECT_EQ(Instr1->DebugMarker->StoredDbgRecords.size(), 2u); 279 // We should de-allocate the trailing marker when something is inserted 280 // at end(). 281 EXPECT_EQ(BB.getTrailingDbgRecords(), nullptr); 282 283 // Remove Instr1: now the DbgVariableRecords will fall down again, 284 Instr1->removeFromParent(); 285 EndMarker = BB.getTrailingDbgRecords(); 286 EXPECT_EQ(EndMarker->StoredDbgRecords.size(), 2u); 287 288 // Inserting a terminator, however it's intended, should dislodge the 289 // trailing DbgVariableRecords, as it's the clear intention of the caller that 290 // this be the final instr in the block, and DbgVariableRecords aren't allowed 291 // to live off the end forever. 292 Instr2->insertBefore(BB, BB.begin()); 293 EXPECT_EQ(Instr2->DebugMarker->StoredDbgRecords.size(), 2u); 294 EXPECT_EQ(BB.getTrailingDbgRecords(), nullptr); 295 296 // Teardown, 297 Instr1->insertBefore(BB, BB.begin()); 298 299 UseNewDbgInfoFormat = false; 300 } 301 302 TEST(BasicBlockDbgInfoTest, HeadBitOperations) { 303 LLVMContext C; 304 UseNewDbgInfoFormat = true; 305 306 std::unique_ptr<Module> M = parseIR(C, R"( 307 define i16 @f(i16 %a) !dbg !6 { 308 %b = add i16 %a, 1, !dbg !11 309 call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 310 %c = add i16 %a, 1, !dbg !11 311 %d = add i16 %a, 1, !dbg !11 312 ret i16 0, !dbg !11 313 } 314 declare void @llvm.dbg.value(metadata, metadata, metadata) #0 315 attributes #0 = { nounwind readnone speculatable willreturn } 316 317 !llvm.dbg.cu = !{!0} 318 !llvm.module.flags = !{!5} 319 320 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 321 !1 = !DIFile(filename: "t.ll", directory: "/") 322 !2 = !{} 323 !5 = !{i32 2, !"Debug Info Version", i32 3} 324 !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8) 325 !7 = !DISubroutineType(types: !2) 326 !8 = !{!9} 327 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) 328 !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned) 329 !11 = !DILocation(line: 1, column: 1, scope: !6) 330 )"); 331 332 // Test that the movement of debug-data when using moveBefore etc and 333 // insertBefore etc are governed by the "head" bit of iterators. 334 BasicBlock &BB = M->getFunction("f")->getEntryBlock(); 335 // Convert the module to "new" form debug-info. 336 M->convertToNewDbgValues(); 337 338 // Test that the head bit behaves as expected: it should be set when the 339 // code wants the _start_ of the block, but not otherwise. 340 EXPECT_TRUE(BB.getFirstInsertionPt().getHeadBit()); 341 BasicBlock::iterator BeginIt = BB.begin(); 342 EXPECT_TRUE(BeginIt.getHeadBit()); 343 // If you launder the instruction pointer through dereferencing and then 344 // get the iterator again with getIterator, the head bit is lost. This is 345 // deliberate: if you're calling getIterator, then you're requesting an 346 // iterator for the position of _this_ instruction, not "the start of this 347 // block". 348 BasicBlock::iterator BeginIt2 = BeginIt->getIterator(); 349 EXPECT_FALSE(BeginIt2.getHeadBit()); 350 351 // Fetch some instruction pointers. 352 Instruction *BInst = &*BeginIt; 353 Instruction *CInst = BInst->getNextNode(); 354 Instruction *DInst = CInst->getNextNode(); 355 // CInst should have debug-info. 356 ASSERT_TRUE(CInst->DebugMarker); 357 EXPECT_FALSE(CInst->DebugMarker->StoredDbgRecords.empty()); 358 359 // If we move "c" to the start of the block, just normally, then the 360 // DbgVariableRecords should fall down to "d". 361 CInst->moveBefore(BB, BeginIt2); 362 EXPECT_TRUE(!CInst->DebugMarker || 363 CInst->DebugMarker->StoredDbgRecords.empty()); 364 ASSERT_TRUE(DInst->DebugMarker); 365 EXPECT_FALSE(DInst->DebugMarker->StoredDbgRecords.empty()); 366 367 // Wheras if we move D to the start of the block with moveBeforePreserving, 368 // the DbgVariableRecords should move with it. 369 DInst->moveBeforePreserving(BB, BB.begin()); 370 EXPECT_FALSE(DInst->DebugMarker->StoredDbgRecords.empty()); 371 EXPECT_EQ(&*BB.begin(), DInst); 372 373 // Similarly, moveAfterPreserving "D" to "C" should move DbgVariableRecords 374 // with "D". 375 DInst->moveAfterPreserving(CInst); 376 EXPECT_FALSE(DInst->DebugMarker->StoredDbgRecords.empty()); 377 378 // (move back to the start...) 379 DInst->moveBeforePreserving(BB, BB.begin()); 380 381 // Current order of insts: "D -> C -> B -> Ret". DbgVariableRecords on "D". 382 // If we move "C" to the beginning of the block, it should go before the 383 // DbgVariableRecords. They'll stay on "D". 384 CInst->moveBefore(BB, BB.begin()); 385 EXPECT_TRUE(!CInst->DebugMarker || 386 CInst->DebugMarker->StoredDbgRecords.empty()); 387 EXPECT_FALSE(DInst->DebugMarker->StoredDbgRecords.empty()); 388 EXPECT_EQ(&*BB.begin(), CInst); 389 EXPECT_EQ(CInst->getNextNode(), DInst); 390 391 // Move back. 392 CInst->moveBefore(BInst); 393 EXPECT_EQ(&*BB.begin(), DInst); 394 395 // Current order of insts: "D -> C -> B -> Ret". DbgVariableRecords on "D". 396 // Now move CInst to the position of DInst, but using getIterator instead of 397 // BasicBlock::begin. This signals that we want the "C" instruction to be 398 // immediately before "D", with any DbgVariableRecords on "D" now moving to 399 // "C". It's the equivalent of moving an instruction to the position between a 400 // run of dbg.values and the next instruction. 401 CInst->moveBefore(BB, DInst->getIterator()); 402 // CInst gains the DbgVariableRecords. 403 EXPECT_TRUE(!DInst->DebugMarker || 404 DInst->DebugMarker->StoredDbgRecords.empty()); 405 EXPECT_FALSE(CInst->DebugMarker->StoredDbgRecords.empty()); 406 EXPECT_EQ(&*BB.begin(), CInst); 407 408 UseNewDbgInfoFormat = false; 409 } 410 411 TEST(BasicBlockDbgInfoTest, InstrDbgAccess) { 412 LLVMContext C; 413 UseNewDbgInfoFormat = true; 414 415 std::unique_ptr<Module> M = parseIR(C, R"( 416 define i16 @f(i16 %a) !dbg !6 { 417 %b = add i16 %a, 1, !dbg !11 418 call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 419 %c = add i16 %a, 1, !dbg !11 420 %d = add i16 %a, 1, !dbg !11 421 ret i16 0, !dbg !11 422 } 423 declare void @llvm.dbg.value(metadata, metadata, metadata) #0 424 attributes #0 = { nounwind readnone speculatable willreturn } 425 426 !llvm.dbg.cu = !{!0} 427 !llvm.module.flags = !{!5} 428 429 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 430 !1 = !DIFile(filename: "t.ll", directory: "/") 431 !2 = !{} 432 !5 = !{i32 2, !"Debug Info Version", i32 3} 433 !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8) 434 !7 = !DISubroutineType(types: !2) 435 !8 = !{!9} 436 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) 437 !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned) 438 !11 = !DILocation(line: 1, column: 1, scope: !6) 439 )"); 440 441 // Check that DbgVariableRecords can be accessed from Instructions without 442 // digging into the depths of DbgMarkers. 443 BasicBlock &BB = M->getFunction("f")->getEntryBlock(); 444 // Convert the module to "new" form debug-info. 445 M->convertToNewDbgValues(); 446 447 Instruction *BInst = &*BB.begin(); 448 Instruction *CInst = BInst->getNextNode(); 449 Instruction *DInst = CInst->getNextNode(); 450 451 ASSERT_FALSE(BInst->DebugMarker); 452 ASSERT_TRUE(CInst->DebugMarker); 453 ASSERT_EQ(CInst->DebugMarker->StoredDbgRecords.size(), 1u); 454 DbgRecord *DVR1 = &*CInst->DebugMarker->StoredDbgRecords.begin(); 455 ASSERT_TRUE(DVR1); 456 EXPECT_FALSE(BInst->hasDbgRecords()); 457 458 // Clone DbgVariableRecords from one inst to another. Other arguments to clone 459 // are tested in DbgMarker test. 460 auto Range1 = BInst->cloneDebugInfoFrom(CInst); 461 EXPECT_EQ(BInst->DebugMarker->StoredDbgRecords.size(), 1u); 462 DbgRecord *DVR2 = &*BInst->DebugMarker->StoredDbgRecords.begin(); 463 EXPECT_EQ(std::distance(Range1.begin(), Range1.end()), 1u); 464 EXPECT_EQ(&*Range1.begin(), DVR2); 465 EXPECT_NE(DVR1, DVR2); 466 467 // We should be able to get a range over exactly the same information. 468 auto Range2 = BInst->getDbgRecordRange(); 469 EXPECT_EQ(Range1.begin(), Range2.begin()); 470 EXPECT_EQ(Range1.end(), Range2.end()); 471 472 // We should be able to query if there are DbgVariableRecords, 473 EXPECT_TRUE(BInst->hasDbgRecords()); 474 EXPECT_TRUE(CInst->hasDbgRecords()); 475 EXPECT_FALSE(DInst->hasDbgRecords()); 476 477 // Dropping should be easy, 478 BInst->dropDbgRecords(); 479 EXPECT_FALSE(BInst->hasDbgRecords()); 480 EXPECT_EQ(BInst->DebugMarker->StoredDbgRecords.size(), 0u); 481 482 // And we should be able to drop individual DbgVariableRecords. 483 CInst->dropOneDbgRecord(DVR1); 484 EXPECT_FALSE(CInst->hasDbgRecords()); 485 EXPECT_EQ(CInst->DebugMarker->StoredDbgRecords.size(), 0u); 486 487 UseNewDbgInfoFormat = false; 488 } 489 490 /* Let's recall the big illustration from BasicBlock::spliceDebugInfo: 491 492 Dest 493 | 494 this-block: A----A----A ====A----A----A----A---A---A 495 Src-block ++++B---B---B---B:::C 496 | | 497 First Last 498 499 in all it's glory. Depending on the bit-configurations for the iterator head 500 / tail bits on the three named iterators, there are eight ways for a splice to 501 occur. To save the amount of thinking needed to pack this into one unit test, 502 just test the same IR eight times with difference splices. The IR shall be 503 thus: 504 505 define i16 @f(i16 %a) !dbg !6 { 506 entry: 507 call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 508 %b = add i16 %a, 1, !dbg !11 509 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 510 br label %exit, !dbg !11 511 512 exit: 513 call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 514 %c = add i16 %b, 1, !dbg !11 515 ret i16 0, !dbg !11 516 } 517 518 The iterators will be: 519 Dest: exit block, "c" instruction. 520 First: entry block, "b" instruction. 521 Last: entry block, branch instruction. 522 523 The numbered configurations will be: 524 525 | Dest-Head | First-Head | Last-tail 526 ----+----------------+----------------+------------ 527 0 | false | false | false 528 1 | true | false | false 529 2 | false | true | false 530 3 | true | true | false 531 4 | false | false | true 532 5 | true | false | true 533 6 | false | true | true 534 7 | true | true | true 535 536 Each numbered test scenario will also have a short explanation indicating what 537 this bit configuration represents. 538 */ 539 540 static const std::string SpliceTestIR = R"( 541 define i16 @f(i16 %a) !dbg !6 { 542 call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 543 %b = add i16 %a, 1, !dbg !11 544 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 545 br label %exit, !dbg !11 546 547 exit: 548 call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 549 %c = add i16 %b, 1, !dbg !11 550 ret i16 0, !dbg !11 551 } 552 declare void @llvm.dbg.value(metadata, metadata, metadata) #0 553 attributes #0 = { nounwind readnone speculatable willreturn } 554 555 !llvm.dbg.cu = !{!0} 556 !llvm.module.flags = !{!5} 557 558 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 559 !1 = !DIFile(filename: "t.ll", directory: "/") 560 !2 = !{} 561 !5 = !{i32 2, !"Debug Info Version", i32 3} 562 !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8) 563 !7 = !DISubroutineType(types: !2) 564 !8 = !{!9} 565 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) 566 !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned) 567 !11 = !DILocation(line: 1, column: 1, scope: !6) 568 )"; 569 570 class DbgSpliceTest : public ::testing::Test { 571 protected: 572 LLVMContext C; 573 std::unique_ptr<Module> M; 574 BasicBlock *BBEntry, *BBExit; 575 BasicBlock::iterator Dest, First, Last; 576 Instruction *BInst, *Branch, *CInst; 577 DbgVariableRecord *DVRA, *DVRB, *DVRConst; 578 579 void SetUp() override { 580 UseNewDbgInfoFormat = true; 581 M = parseIR(C, SpliceTestIR.c_str()); 582 M->convertToNewDbgValues(); 583 584 BBEntry = &M->getFunction("f")->getEntryBlock(); 585 BBExit = BBEntry->getNextNode(); 586 587 Dest = BBExit->begin(); 588 First = BBEntry->begin(); 589 Last = BBEntry->getTerminator()->getIterator(); 590 BInst = &*First; 591 Branch = &*Last; 592 CInst = &*Dest; 593 594 DVRA = 595 cast<DbgVariableRecord>(&*BInst->DebugMarker->StoredDbgRecords.begin()); 596 DVRB = cast<DbgVariableRecord>( 597 &*Branch->DebugMarker->StoredDbgRecords.begin()); 598 DVRConst = 599 cast<DbgVariableRecord>(&*CInst->DebugMarker->StoredDbgRecords.begin()); 600 } 601 602 void TearDown() override { UseNewDbgInfoFormat = false; } 603 604 bool InstContainsDbgVariableRecord(Instruction *I, DbgVariableRecord *DVR) { 605 for (DbgRecord &D : I->getDbgRecordRange()) { 606 if (&D == DVR) { 607 // Confirm too that the links between the records are correct. 608 EXPECT_EQ(DVR->Marker, I->DebugMarker); 609 EXPECT_EQ(I->DebugMarker->MarkedInstr, I); 610 return true; 611 } 612 } 613 return false; 614 } 615 616 bool CheckDVROrder(Instruction *I, 617 SmallVector<DbgVariableRecord *> CheckVals) { 618 SmallVector<DbgRecord *> Vals; 619 for (DbgRecord &D : I->getDbgRecordRange()) 620 Vals.push_back(&D); 621 622 EXPECT_EQ(Vals.size(), CheckVals.size()); 623 if (Vals.size() != CheckVals.size()) 624 return false; 625 626 for (unsigned int I = 0; I < Vals.size(); ++I) { 627 EXPECT_EQ(Vals[I], CheckVals[I]); 628 // Provide another expectation failure to let us localise what goes wrong, 629 // by returning a flag to the caller. 630 if (Vals[I] != CheckVals[I]) 631 return false; 632 } 633 return true; 634 } 635 }; 636 637 TEST_F(DbgSpliceTest, DbgSpliceTest0) { 638 Dest.setHeadBit(false); 639 First.setHeadBit(false); 640 Last.setTailBit(false); 641 642 /* 643 define i16 @f(i16 %a) !dbg !6 { 644 BBEntry entry: 645 DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata 646 !DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call 647 void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), 648 !dbg !11 Last br label %exit, !dbg !11 649 650 BBExit exit: 651 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata 652 !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, 653 !dbg !11 654 } 655 656 Splice from First, not including leading dbg.value, to Last, including the 657 trailing dbg.value. Place at Dest, between the constant dbg.value and %c. 658 %b, and the following dbg.value, should move, to: 659 660 define i16 @f(i16 %a) !dbg !6 { 661 BBEntry entry: 662 DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata 663 !DIExpression()), !dbg !11 Last br label %exit, !dbg !11 664 665 BBExit exit: 666 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata 667 !DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call 668 void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), 669 !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, !dbg !11 670 } 671 672 673 */ 674 BBExit->splice(Dest, BBEntry, First, Last); 675 EXPECT_EQ(BInst->getParent(), BBExit); 676 EXPECT_EQ(CInst->getParent(), BBExit); 677 EXPECT_EQ(Branch->getParent(), BBEntry); 678 679 // DVRB: should be on Dest, in exit block. 680 EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRB)); 681 682 // DVRA, should have "fallen" onto the branch, remained in entry block. 683 EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRA)); 684 685 // DVRConst should be on the moved %b instruction. 686 EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRConst)); 687 } 688 689 TEST_F(DbgSpliceTest, DbgSpliceTest1) { 690 Dest.setHeadBit(true); 691 First.setHeadBit(false); 692 Last.setTailBit(false); 693 694 /* 695 define i16 @f(i16 %a) !dbg !6 { 696 BBEntry entry: 697 DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata 698 !DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call 699 void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), 700 !dbg !11 Last br label %exit, !dbg !11 701 702 BBExit exit: 703 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata 704 !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, 705 !dbg !11 706 } 707 708 Splice from First, not including leading dbg.value, to Last, including the 709 trailing dbg.value. Place at the head of Dest, i.e. at the very start of 710 BBExit, before any debug-info there. Becomes: 711 712 define i16 @f(i16 %a) !dbg !6 { 713 BBEntry entry: 714 DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata 715 !DIExpression()), !dbg !11 Last br label %exit, !dbg !11 716 717 BBExit exit: 718 First %b = add i16 %a, 1, !dbg !11 719 DVRB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata 720 !DIExpression()), !dbg !11 DVRConst call void @llvm.dbg.value(metadata i16 0, 721 metadata !9, metadata !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, 722 !dbg !11 ret i16 0, !dbg !11 723 } 724 725 726 */ 727 BBExit->splice(Dest, BBEntry, First, Last); 728 EXPECT_EQ(BInst->getParent(), BBExit); 729 EXPECT_EQ(CInst->getParent(), BBExit); 730 EXPECT_EQ(Branch->getParent(), BBEntry); 731 732 // DVRB: should be on CInst, in exit block. 733 EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRB)); 734 735 // DVRA, should have "fallen" onto the branch, remained in entry block. 736 EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRA)); 737 738 // DVRConst should be behind / after the moved instructions, remain on CInst. 739 EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst)); 740 741 // Order of DVRB and DVRConst should be thus: 742 EXPECT_TRUE(CheckDVROrder(CInst, {DVRB, DVRConst})); 743 } 744 745 TEST_F(DbgSpliceTest, DbgSpliceTest2) { 746 Dest.setHeadBit(false); 747 First.setHeadBit(true); 748 Last.setTailBit(false); 749 750 /* 751 define i16 @f(i16 %a) !dbg !6 { 752 BBEntry entry: 753 DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata 754 !DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call 755 void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), 756 !dbg !11 Last br label %exit, !dbg !11 757 758 BBExit exit: 759 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata 760 !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, 761 !dbg !11 762 } 763 764 Splice from head of First, which includes the leading dbg.value, to Last, 765 including the trailing dbg.value. Place in front of Dest, but after any 766 debug-info there. Becomes: 767 768 define i16 @f(i16 %a) !dbg !6 { 769 BBEntry entry: 770 Last br label %exit, !dbg !11 771 772 BBExit exit: 773 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata 774 !DIExpression()), !dbg !11 DVRA call void @llvm.dbg.value(metadata i16 %a, 775 metadata !9, metadata !DIExpression()), !dbg !11 First %b = add i16 %a, 1, 776 !dbg !11 DVRB call void @llvm.dbg.value(metadata i16 %b, metadata !9, 777 metadata !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret 778 i16 0, !dbg !11 779 } 780 781 782 */ 783 BBExit->splice(Dest, BBEntry, First, Last); 784 EXPECT_EQ(BInst->getParent(), BBExit); 785 EXPECT_EQ(CInst->getParent(), BBExit); 786 787 // DVRB: should be on CInst, in exit block. 788 EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRB)); 789 790 // DVRA, should have transferred with the spliced instructions, remains on 791 // the "b" inst. 792 EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRA)); 793 794 // DVRConst should be ahead of the moved instructions, ahead of BInst. 795 EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRConst)); 796 797 // Order of DVRA and DVRConst should be thus: 798 EXPECT_TRUE(CheckDVROrder(BInst, {DVRConst, DVRA})); 799 } 800 801 TEST_F(DbgSpliceTest, DbgSpliceTest3) { 802 Dest.setHeadBit(true); 803 First.setHeadBit(true); 804 Last.setTailBit(false); 805 806 /* 807 define i16 @f(i16 %a) !dbg !6 { 808 BBEntry entry: 809 DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata 810 !DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call 811 void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), 812 !dbg !11 Last br label %exit, !dbg !11 813 814 BBExit exit: 815 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata 816 !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, 817 !dbg !11 818 } 819 820 Splice from head of First, which includes the leading dbg.value, to Last, 821 including the trailing dbg.value. Place at head of Dest, before any 822 debug-info there. Becomes: 823 824 define i16 @f(i16 %a) !dbg !6 { 825 BBEntry entry: 826 Last br label %exit, !dbg !11 827 828 BBExit exit: 829 DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata 830 !DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call 831 void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), 832 !dbg !11 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, 833 metadata !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret 834 i16 0, !dbg !11 835 } 836 837 */ 838 BBExit->splice(Dest, BBEntry, First, Last); 839 EXPECT_EQ(BInst->getParent(), BBExit); 840 EXPECT_EQ(CInst->getParent(), BBExit); 841 842 // DVRB: should be on CInst, in exit block. 843 EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRB)); 844 845 // DVRA, should have transferred with the spliced instructions, remains on 846 // the "b" inst. 847 EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRA)); 848 849 // DVRConst should be behind the moved instructions, ahead of CInst. 850 EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst)); 851 852 // Order of DVRB and DVRConst should be thus: 853 EXPECT_TRUE(CheckDVROrder(CInst, {DVRB, DVRConst})); 854 } 855 856 TEST_F(DbgSpliceTest, DbgSpliceTest4) { 857 Dest.setHeadBit(false); 858 First.setHeadBit(false); 859 Last.setTailBit(true); 860 861 /* 862 define i16 @f(i16 %a) !dbg !6 { 863 BBEntry entry: 864 DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata 865 !DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call 866 void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), 867 !dbg !11 Last br label %exit, !dbg !11 868 869 BBExit exit: 870 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata 871 !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, 872 !dbg !11 873 } 874 875 Splice from First, not including the leading dbg.value, to Last, but NOT 876 including the trailing dbg.value because the tail bit is set. Place at Dest, 877 after any debug-info there. Becomes: 878 879 define i16 @f(i16 %a) !dbg !6 { 880 BBEntry entry: 881 DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata 882 !DIExpression()), !dbg !11 DVRB call void @llvm.dbg.value(metadata i16 %b, 883 metadata !9, metadata !DIExpression()), !dbg !11 Last br label %exit, !dbg 884 !11 885 886 BBExit exit: 887 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata 888 !DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 Dest %c = 889 add i16 %b, 1, !dbg !11 ret i16 0, !dbg !11 890 } 891 892 */ 893 BBExit->splice(Dest, BBEntry, First, Last); 894 EXPECT_EQ(BInst->getParent(), BBExit); 895 EXPECT_EQ(CInst->getParent(), BBExit); 896 EXPECT_EQ(Branch->getParent(), BBEntry); 897 898 // DVRB: should be on Branch as before, remain in entry block. 899 EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB)); 900 901 // DVRA, should have remained in entry block, falls onto Branch inst. 902 EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRA)); 903 904 // DVRConst should be ahead of the moved instructions, BInst. 905 EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRConst)); 906 907 // Order of DVRA and DVRA should be thus: 908 EXPECT_TRUE(CheckDVROrder(Branch, {DVRA, DVRB})); 909 } 910 911 TEST_F(DbgSpliceTest, DbgSpliceTest5) { 912 Dest.setHeadBit(true); 913 First.setHeadBit(false); 914 Last.setTailBit(true); 915 916 /* 917 define i16 @f(i16 %a) !dbg !6 { 918 BBEntry entry: 919 DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata 920 !DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call 921 void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), 922 !dbg !11 Last br label %exit, !dbg !11 923 924 BBExit exit: 925 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata 926 !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, 927 !dbg !11 928 } 929 930 Splice from First, not including the leading dbg.value, to Last, but NOT 931 including the trailing dbg.value because the tail bit is set. Place at head 932 of Dest, before any debug-info there. Becomes: 933 934 define i16 @f(i16 %a) !dbg !6 { 935 BBEntry entry: 936 DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata 937 !DIExpression()), !dbg !11 DVRB call void @llvm.dbg.value(metadata i16 %b, 938 metadata !9, metadata !DIExpression()), !dbg !11 Last br label %exit, !dbg 939 !11 940 941 BBExit exit: 942 First %b = add i16 %a, 1, !dbg !11 943 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata 944 !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, 945 !dbg !11 946 } 947 948 */ 949 BBExit->splice(Dest, BBEntry, First, Last); 950 EXPECT_EQ(BInst->getParent(), BBExit); 951 EXPECT_EQ(CInst->getParent(), BBExit); 952 EXPECT_EQ(Branch->getParent(), BBEntry); 953 954 // DVRB: should be on Branch as before, remain in entry block. 955 EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB)); 956 957 // DVRA, should have remained in entry block, falls onto Branch inst. 958 EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRA)); 959 960 // DVRConst should be behind of the moved instructions, on CInst. 961 EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst)); 962 963 // Order of DVRA and DVRB should be thus: 964 EXPECT_TRUE(CheckDVROrder(Branch, {DVRA, DVRB})); 965 } 966 967 TEST_F(DbgSpliceTest, DbgSpliceTest6) { 968 Dest.setHeadBit(false); 969 First.setHeadBit(true); 970 Last.setTailBit(true); 971 972 /* 973 define i16 @f(i16 %a) !dbg !6 { 974 BBEntry entry: 975 DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata 976 !DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call 977 void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), 978 !dbg !11 Last br label %exit, !dbg !11 979 980 BBExit exit: 981 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata 982 !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, 983 !dbg !11 984 } 985 986 Splice from First, including the leading dbg.value, to Last, but NOT 987 including the trailing dbg.value because the tail bit is set. Place at Dest, 988 after any debug-info there. Becomes: 989 990 define i16 @f(i16 %a) !dbg !6 { 991 BBEntry entry: 992 DVRB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata 993 !DIExpression()), !dbg !11 Last br label %exit, !dbg !11 994 995 BBExit exit: 996 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata 997 !DIExpression()), !dbg !11 DVRA call void @llvm.dbg.value(metadata i16 %a, 998 metadata !9, metadata !DIExpression()), !dbg !11 First %b = add i16 %a, 1, 999 !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, !dbg !11 1000 } 1001 1002 */ 1003 BBExit->splice(Dest, BBEntry, First, Last); 1004 EXPECT_EQ(BInst->getParent(), BBExit); 1005 EXPECT_EQ(CInst->getParent(), BBExit); 1006 EXPECT_EQ(Branch->getParent(), BBEntry); 1007 1008 // DVRB: should be on Branch as before, remain in entry block. 1009 EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB)); 1010 1011 // DVRA, should have transferred to BBExit, on B inst. 1012 EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRA)); 1013 1014 // DVRConst should be ahead of the moved instructions, on BInst. 1015 EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRConst)); 1016 1017 // Order of DVRA and DVRConst should be thus: 1018 EXPECT_TRUE(CheckDVROrder(BInst, {DVRConst, DVRA})); 1019 } 1020 1021 TEST_F(DbgSpliceTest, DbgSpliceTest7) { 1022 Dest.setHeadBit(true); 1023 First.setHeadBit(true); 1024 Last.setTailBit(true); 1025 1026 /* 1027 define i16 @f(i16 %a) !dbg !6 { 1028 BBEntry entry: 1029 DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata 1030 !DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call 1031 void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), 1032 !dbg !11 Last br label %exit, !dbg !11 1033 1034 BBExit exit: 1035 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata 1036 !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, 1037 !dbg !11 1038 } 1039 1040 Splice from First, including the leading dbg.value, to Last, but NOT 1041 including the trailing dbg.value because the tail bit is set. Place at head 1042 of Dest, before any debug-info there. Becomes: 1043 1044 define i16 @f(i16 %a) !dbg !6 { 1045 BBEntry entry: 1046 DVRB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata 1047 !DIExpression()), !dbg !11 Last br label %exit, !dbg !11 1048 1049 BBExit exit: 1050 DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata 1051 !DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRConst call 1052 void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), 1053 !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, !dbg !11 1054 } 1055 1056 */ 1057 BBExit->splice(Dest, BBEntry, First, Last); 1058 EXPECT_EQ(BInst->getParent(), BBExit); 1059 EXPECT_EQ(CInst->getParent(), BBExit); 1060 EXPECT_EQ(Branch->getParent(), BBEntry); 1061 1062 // DVRB: should be on Branch as before, remain in entry block. 1063 EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB)); 1064 1065 // DVRA, should have transferred to BBExit, on B inst. 1066 EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRA)); 1067 1068 // DVRConst should be after of the moved instructions, on CInst. 1069 EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst)); 1070 } 1071 1072 // But wait, there's more! What if you splice a range that is empty, but 1073 // implicitly contains debug-info? In the dbg.value design for debug-info, 1074 // this would be an explicit range, but in DbgVariableRecord debug-info, it 1075 // isn't. Check that if we try to do that, with differing head-bit values, that 1076 // DbgVariableRecords are transferred. 1077 // Test with empty transfers to Dest, with head bit set and not set. 1078 1079 TEST_F(DbgSpliceTest, DbgSpliceEmpty0) { 1080 Dest.setHeadBit(false); 1081 First.setHeadBit(false); 1082 Last.setHeadBit(false); 1083 /* 1084 define i16 @f(i16 %a) !dbg !6 { 1085 BBEntry entry: 1086 DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata 1087 !DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call 1088 void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), 1089 !dbg !11 Last br label %exit, !dbg !11 1090 1091 BBExit exit: 1092 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata 1093 !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, 1094 !dbg !11 1095 } 1096 1097 Splice from BBEntry.getFirstInsertionPt to First -- this implicitly is a 1098 splice of DVRA, but the iterators are pointing at the same instruction. The 1099 only difference is the setting of the head bit. Becomes; 1100 1101 define i16 @f(i16 %a) !dbg !6 { 1102 First %b = add i16 %a, 1, !dbg !11 1103 DVRB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata 1104 !DIExpression()), !dbg !11 Last br label %exit, !dbg !11 1105 1106 BBExit exit: 1107 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata 1108 !DIExpression()), !dbg !11 DVRA call void @llvm.dbg.value(metadata i16 %a, 1109 metadata !9, metadata !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, 1110 !dbg !11 ret i16 0, !dbg !11 1111 } 1112 1113 */ 1114 BBExit->splice(Dest, BBEntry, BBEntry->getFirstInsertionPt(), First); 1115 EXPECT_EQ(BInst->getParent(), BBEntry); 1116 EXPECT_EQ(CInst->getParent(), BBExit); 1117 EXPECT_EQ(Branch->getParent(), BBEntry); 1118 1119 // DVRB: should be on Branch as before, remain in entry block. 1120 EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB)); 1121 1122 // DVRA, should have transferred to BBExit, on C inst. 1123 EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRA)); 1124 1125 // DVRConst should be ahead of the moved DbgVariableRecord, on CInst. 1126 EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst)); 1127 1128 // Order of DVRA and DVRConst should be thus: 1129 EXPECT_TRUE(CheckDVROrder(CInst, {DVRConst, DVRA})); 1130 } 1131 1132 TEST_F(DbgSpliceTest, DbgSpliceEmpty1) { 1133 Dest.setHeadBit(true); 1134 First.setHeadBit(false); 1135 Last.setHeadBit(false); 1136 /* 1137 define i16 @f(i16 %a) !dbg !6 { 1138 BBEntry entry: 1139 DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata 1140 !DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call 1141 void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), 1142 !dbg !11 Last br label %exit, !dbg !11 1143 1144 BBExit exit: 1145 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata 1146 !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, 1147 !dbg !11 1148 } 1149 1150 Splice from BBEntry.getFirstInsertionPt to First -- this implicitly is a 1151 splice of DVRA, but the iterators are pointing at the same instruction. The 1152 only difference is the setting of the head bit. Insert at head of Dest, 1153 i.e. before DVRConst. Becomes; 1154 1155 define i16 @f(i16 %a) !dbg !6 { 1156 First %b = add i16 %a, 1, !dbg !11 1157 DVRB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata 1158 !DIExpression()), !dbg !11 Last br label %exit, !dbg !11 1159 1160 BBExit exit: 1161 DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata 1162 !DIExpression()), !dbg !11 DVRConst call void @llvm.dbg.value(metadata i16 0, 1163 metadata !9, metadata !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, 1164 !dbg !11 ret i16 0, !dbg !11 1165 } 1166 1167 */ 1168 BBExit->splice(Dest, BBEntry, BBEntry->getFirstInsertionPt(), First); 1169 EXPECT_EQ(BInst->getParent(), BBEntry); 1170 EXPECT_EQ(CInst->getParent(), BBExit); 1171 EXPECT_EQ(Branch->getParent(), BBEntry); 1172 1173 // DVRB: should be on Branch as before, remain in entry block. 1174 EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB)); 1175 1176 // DVRA, should have transferred to BBExit, on C inst. 1177 EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRA)); 1178 1179 // DVRConst should be ahead of the moved DbgVariableRecord, on CInst. 1180 EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst)); 1181 1182 // Order of DVRA and DVRConst should be thus: 1183 EXPECT_TRUE(CheckDVROrder(CInst, {DVRA, DVRConst})); 1184 } 1185 1186 // If we splice new instructions into a block with trailing DbgVariableRecords, 1187 // then the trailing DbgVariableRecords should get flushed back out. 1188 TEST(BasicBlockDbgInfoTest, DbgSpliceTrailing) { 1189 LLVMContext C; 1190 UseNewDbgInfoFormat = true; 1191 1192 std::unique_ptr<Module> M = parseIR(C, R"( 1193 define i16 @f(i16 %a) !dbg !6 { 1194 entry: 1195 call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 1196 br label %exit 1197 1198 exit: 1199 %b = add i16 %a, 1, !dbg !11 1200 ret i16 0, !dbg !11 1201 } 1202 declare void @llvm.dbg.value(metadata, metadata, metadata) #0 1203 attributes #0 = { nounwind readnone speculatable willreturn } 1204 1205 !llvm.dbg.cu = !{!0} 1206 !llvm.module.flags = !{!5} 1207 1208 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 1209 !1 = !DIFile(filename: "t.ll", directory: "/") 1210 !2 = !{} 1211 !5 = !{i32 2, !"Debug Info Version", i32 3} 1212 !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8) 1213 !7 = !DISubroutineType(types: !2) 1214 !8 = !{!9} 1215 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) 1216 !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned) 1217 !11 = !DILocation(line: 1, column: 1, scope: !6) 1218 )"); 1219 1220 BasicBlock &Entry = M->getFunction("f")->getEntryBlock(); 1221 BasicBlock &Exit = *Entry.getNextNode(); 1222 M->convertToNewDbgValues(); 1223 1224 // Begin by forcing entry block to have dangling DbgVariableRecord. 1225 Entry.getTerminator()->eraseFromParent(); 1226 ASSERT_NE(Entry.getTrailingDbgRecords(), nullptr); 1227 EXPECT_TRUE(Entry.empty()); 1228 1229 // Now transfer the entire contents of the exit block into the entry. 1230 Entry.splice(Entry.end(), &Exit, Exit.begin(), Exit.end()); 1231 1232 // The trailing DbgVariableRecord should have been placed at the front of 1233 // what's been spliced in. 1234 Instruction *BInst = &*Entry.begin(); 1235 ASSERT_TRUE(BInst->DebugMarker); 1236 EXPECT_EQ(BInst->DebugMarker->StoredDbgRecords.size(), 1u); 1237 1238 UseNewDbgInfoFormat = false; 1239 } 1240 1241 // When we remove instructions from the program, adjacent DbgVariableRecords 1242 // coalesce together into one DbgMarker. In "old" dbg.value mode you could 1243 // re-insert the removed instruction back into the middle of a sequence of 1244 // dbg.values. Test that this can be replicated correctly by DbgVariableRecords 1245 TEST(BasicBlockDbgInfoTest, RemoveInstAndReinsert) { 1246 LLVMContext C; 1247 UseNewDbgInfoFormat = true; 1248 1249 std::unique_ptr<Module> M = parseIR(C, R"( 1250 define i16 @f(i16 %a) !dbg !6 { 1251 entry: 1252 %qux = sub i16 %a, 0 1253 call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 1254 %foo = add i16 %a, %a 1255 call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 1256 ret i16 1 1257 } 1258 declare void @llvm.dbg.value(metadata, metadata, metadata) 1259 1260 !llvm.dbg.cu = !{!0} 1261 !llvm.module.flags = !{!5} 1262 1263 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 1264 !1 = !DIFile(filename: "t.ll", directory: "/") 1265 !2 = !{} 1266 !5 = !{i32 2, !"Debug Info Version", i32 3} 1267 !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8) 1268 !7 = !DISubroutineType(types: !2) 1269 !8 = !{!9} 1270 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) 1271 !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned) 1272 !11 = !DILocation(line: 1, column: 1, scope: !6) 1273 )"); 1274 1275 BasicBlock &Entry = M->getFunction("f")->getEntryBlock(); 1276 M->convertToNewDbgValues(); 1277 1278 // Fetch the relevant instructions from the converted function. 1279 Instruction *SubInst = &*Entry.begin(); 1280 ASSERT_TRUE(isa<BinaryOperator>(SubInst)); 1281 Instruction *AddInst = SubInst->getNextNode(); 1282 ASSERT_TRUE(isa<BinaryOperator>(AddInst)); 1283 Instruction *RetInst = AddInst->getNextNode(); 1284 ASSERT_TRUE(isa<ReturnInst>(RetInst)); 1285 1286 // add and sub should both have one DbgVariableRecord on add and ret. 1287 EXPECT_FALSE(SubInst->hasDbgRecords()); 1288 EXPECT_TRUE(AddInst->hasDbgRecords()); 1289 EXPECT_TRUE(RetInst->hasDbgRecords()); 1290 auto R1 = AddInst->getDbgRecordRange(); 1291 EXPECT_EQ(std::distance(R1.begin(), R1.end()), 1u); 1292 auto R2 = RetInst->getDbgRecordRange(); 1293 EXPECT_EQ(std::distance(R2.begin(), R2.end()), 1u); 1294 1295 // The Supported (TM) code sequence for removing then reinserting insts 1296 // after another instruction: 1297 std::optional<DbgVariableRecord::self_iterator> Pos = 1298 AddInst->getDbgReinsertionPosition(); 1299 AddInst->removeFromParent(); 1300 1301 // We should have a re-insertion position. 1302 ASSERT_TRUE(Pos); 1303 // Both DbgVariableRecords should now be attached to the ret inst. 1304 auto R3 = RetInst->getDbgRecordRange(); 1305 EXPECT_EQ(std::distance(R3.begin(), R3.end()), 2u); 1306 1307 // Re-insert and re-insert. 1308 AddInst->insertAfter(SubInst); 1309 Entry.reinsertInstInDbgRecords(AddInst, Pos); 1310 // We should be back into a position of having one DbgVariableRecord on add 1311 // and ret. 1312 EXPECT_FALSE(SubInst->hasDbgRecords()); 1313 EXPECT_TRUE(AddInst->hasDbgRecords()); 1314 EXPECT_TRUE(RetInst->hasDbgRecords()); 1315 auto R4 = AddInst->getDbgRecordRange(); 1316 EXPECT_EQ(std::distance(R4.begin(), R4.end()), 1u); 1317 auto R5 = RetInst->getDbgRecordRange(); 1318 EXPECT_EQ(std::distance(R5.begin(), R5.end()), 1u); 1319 1320 UseNewDbgInfoFormat = false; 1321 } 1322 1323 // Test instruction removal and re-insertion, this time with one 1324 // DbgVariableRecord that should hop up one instruction. 1325 TEST(BasicBlockDbgInfoTest, RemoveInstAndReinsertForOneDbgVariableRecord) { 1326 LLVMContext C; 1327 UseNewDbgInfoFormat = true; 1328 1329 std::unique_ptr<Module> M = parseIR(C, R"( 1330 define i16 @f(i16 %a) !dbg !6 { 1331 entry: 1332 %qux = sub i16 %a, 0 1333 call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 1334 %foo = add i16 %a, %a 1335 ret i16 1 1336 } 1337 declare void @llvm.dbg.value(metadata, metadata, metadata) 1338 1339 !llvm.dbg.cu = !{!0} 1340 !llvm.module.flags = !{!5} 1341 1342 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 1343 !1 = !DIFile(filename: "t.ll", directory: "/") 1344 !2 = !{} 1345 !5 = !{i32 2, !"Debug Info Version", i32 3} 1346 !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8) 1347 !7 = !DISubroutineType(types: !2) 1348 !8 = !{!9} 1349 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) 1350 !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned) 1351 !11 = !DILocation(line: 1, column: 1, scope: !6) 1352 )"); 1353 1354 BasicBlock &Entry = M->getFunction("f")->getEntryBlock(); 1355 M->convertToNewDbgValues(); 1356 1357 // Fetch the relevant instructions from the converted function. 1358 Instruction *SubInst = &*Entry.begin(); 1359 ASSERT_TRUE(isa<BinaryOperator>(SubInst)); 1360 Instruction *AddInst = SubInst->getNextNode(); 1361 ASSERT_TRUE(isa<BinaryOperator>(AddInst)); 1362 Instruction *RetInst = AddInst->getNextNode(); 1363 ASSERT_TRUE(isa<ReturnInst>(RetInst)); 1364 1365 // There should be one DbgVariableRecord. 1366 EXPECT_FALSE(SubInst->hasDbgRecords()); 1367 EXPECT_TRUE(AddInst->hasDbgRecords()); 1368 EXPECT_FALSE(RetInst->hasDbgRecords()); 1369 auto R1 = AddInst->getDbgRecordRange(); 1370 EXPECT_EQ(std::distance(R1.begin(), R1.end()), 1u); 1371 1372 // The Supported (TM) code sequence for removing then reinserting insts: 1373 std::optional<DbgVariableRecord::self_iterator> Pos = 1374 AddInst->getDbgReinsertionPosition(); 1375 AddInst->removeFromParent(); 1376 1377 // No re-insertion position as there were no DbgVariableRecords on the ret. 1378 ASSERT_FALSE(Pos); 1379 // The single DbgVariableRecord should now be attached to the ret inst. 1380 EXPECT_TRUE(RetInst->hasDbgRecords()); 1381 auto R2 = RetInst->getDbgRecordRange(); 1382 EXPECT_EQ(std::distance(R2.begin(), R2.end()), 1u); 1383 1384 // Re-insert and re-insert. 1385 AddInst->insertAfter(SubInst); 1386 Entry.reinsertInstInDbgRecords(AddInst, Pos); 1387 // We should be back into a position of having one DbgVariableRecord on the 1388 // AddInst. 1389 EXPECT_FALSE(SubInst->hasDbgRecords()); 1390 EXPECT_TRUE(AddInst->hasDbgRecords()); 1391 EXPECT_FALSE(RetInst->hasDbgRecords()); 1392 auto R3 = AddInst->getDbgRecordRange(); 1393 EXPECT_EQ(std::distance(R3.begin(), R3.end()), 1u); 1394 1395 UseNewDbgInfoFormat = false; 1396 } 1397 1398 // Similar to the above, what if we splice into an empty block with debug-info, 1399 // with debug-info at the start of the moving range, that we intend to be 1400 // transferred. The dbg.value of %a should remain at the start, but come ahead 1401 // of the i16 0 dbg.value. 1402 TEST(BasicBlockDbgInfoTest, DbgSpliceToEmpty1) { 1403 LLVMContext C; 1404 UseNewDbgInfoFormat = true; 1405 1406 std::unique_ptr<Module> M = parseIR(C, R"( 1407 define i16 @f(i16 %a) !dbg !6 { 1408 entry: 1409 call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 1410 br label %exit 1411 1412 exit: 1413 call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 1414 %b = add i16 %a, 1, !dbg !11 1415 call void @llvm.dbg.value(metadata i16 1, metadata !9, metadata !DIExpression()), !dbg !11 1416 ret i16 0, !dbg !11 1417 } 1418 declare void @llvm.dbg.value(metadata, metadata, metadata) #0 1419 attributes #0 = { nounwind readnone speculatable willreturn } 1420 1421 !llvm.dbg.cu = !{!0} 1422 !llvm.module.flags = !{!5} 1423 1424 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 1425 !1 = !DIFile(filename: "t.ll", directory: "/") 1426 !2 = !{} 1427 !5 = !{i32 2, !"Debug Info Version", i32 3} 1428 !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8) 1429 !7 = !DISubroutineType(types: !2) 1430 !8 = !{!9} 1431 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) 1432 !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned) 1433 !11 = !DILocation(line: 1, column: 1, scope: !6) 1434 )"); 1435 1436 Function &F = *M->getFunction("f"); 1437 BasicBlock &Entry = F.getEntryBlock(); 1438 BasicBlock &Exit = *Entry.getNextNode(); 1439 M->convertToNewDbgValues(); 1440 1441 // Begin by forcing entry block to have dangling DbgVariableRecord. 1442 Entry.getTerminator()->eraseFromParent(); 1443 ASSERT_NE(Entry.getTrailingDbgRecords(), nullptr); 1444 EXPECT_TRUE(Entry.empty()); 1445 1446 // Now transfer the entire contents of the exit block into the entry. This 1447 // includes both dbg.values. 1448 Entry.splice(Entry.end(), &Exit, Exit.begin(), Exit.end()); 1449 1450 // We should now have two dbg.values on the first instruction, and they 1451 // should be in the correct order of %a, then 0. 1452 Instruction *BInst = &*Entry.begin(); 1453 ASSERT_TRUE(BInst->hasDbgRecords()); 1454 EXPECT_EQ(BInst->DebugMarker->StoredDbgRecords.size(), 2u); 1455 SmallVector<DbgVariableRecord *, 2> DbgVariableRecords; 1456 for (DbgRecord &DVR : BInst->getDbgRecordRange()) 1457 DbgVariableRecords.push_back(cast<DbgVariableRecord>(&DVR)); 1458 1459 EXPECT_EQ(DbgVariableRecords[0]->getVariableLocationOp(0), F.getArg(0)); 1460 Value *SecondDVRValue = DbgVariableRecords[1]->getVariableLocationOp(0); 1461 ASSERT_TRUE(isa<ConstantInt>(SecondDVRValue)); 1462 EXPECT_EQ(cast<ConstantInt>(SecondDVRValue)->getZExtValue(), 0ull); 1463 1464 // No trailing DbgVariableRecords in the entry block now. 1465 EXPECT_EQ(Entry.getTrailingDbgRecords(), nullptr); 1466 1467 UseNewDbgInfoFormat = false; 1468 } 1469 1470 // Similar test again, but this time: splice the contents of exit into entry, 1471 // with the intention of leaving the first dbg.value (i16 0) behind. 1472 TEST(BasicBlockDbgInfoTest, DbgSpliceToEmpty2) { 1473 LLVMContext C; 1474 UseNewDbgInfoFormat = true; 1475 1476 std::unique_ptr<Module> M = parseIR(C, R"( 1477 define i16 @f(i16 %a) !dbg !6 { 1478 entry: 1479 call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 1480 br label %exit 1481 1482 exit: 1483 call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 1484 %b = add i16 %a, 1, !dbg !11 1485 call void @llvm.dbg.value(metadata i16 1, metadata !9, metadata !DIExpression()), !dbg !11 1486 ret i16 0, !dbg !11 1487 } 1488 declare void @llvm.dbg.value(metadata, metadata, metadata) #0 1489 attributes #0 = { nounwind readnone speculatable willreturn } 1490 1491 !llvm.dbg.cu = !{!0} 1492 !llvm.module.flags = !{!5} 1493 1494 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 1495 !1 = !DIFile(filename: "t.ll", directory: "/") 1496 !2 = !{} 1497 !5 = !{i32 2, !"Debug Info Version", i32 3} 1498 !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8) 1499 !7 = !DISubroutineType(types: !2) 1500 !8 = !{!9} 1501 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) 1502 !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned) 1503 !11 = !DILocation(line: 1, column: 1, scope: !6) 1504 )"); 1505 1506 Function &F = *M->getFunction("f"); 1507 BasicBlock &Entry = F.getEntryBlock(); 1508 BasicBlock &Exit = *Entry.getNextNode(); 1509 M->convertToNewDbgValues(); 1510 1511 // Begin by forcing entry block to have dangling DbgVariableRecord. 1512 Entry.getTerminator()->eraseFromParent(); 1513 ASSERT_NE(Entry.getTrailingDbgRecords(), nullptr); 1514 EXPECT_TRUE(Entry.empty()); 1515 1516 // Now transfer into the entry block -- fetching the first instruction with 1517 // begin and then calling getIterator clears the "head" bit, meaning that the 1518 // range to move will not include any leading DbgVariableRecords. 1519 Entry.splice(Entry.end(), &Exit, Exit.begin()->getIterator(), Exit.end()); 1520 1521 // We should now have one dbg.values on the first instruction, %a. 1522 Instruction *BInst = &*Entry.begin(); 1523 ASSERT_TRUE(BInst->hasDbgRecords()); 1524 EXPECT_EQ(BInst->DebugMarker->StoredDbgRecords.size(), 1u); 1525 SmallVector<DbgVariableRecord *, 2> DbgVariableRecords; 1526 for (DbgRecord &DVR : BInst->getDbgRecordRange()) 1527 DbgVariableRecords.push_back(cast<DbgVariableRecord>(&DVR)); 1528 1529 EXPECT_EQ(DbgVariableRecords[0]->getVariableLocationOp(0), F.getArg(0)); 1530 // No trailing DbgVariableRecords in the entry block now. 1531 EXPECT_EQ(Entry.getTrailingDbgRecords(), nullptr); 1532 1533 // We should have nothing left in the exit block... 1534 EXPECT_TRUE(Exit.empty()); 1535 // ... except for some dangling DbgVariableRecords. 1536 EXPECT_NE(Exit.getTrailingDbgRecords(), nullptr); 1537 EXPECT_FALSE(Exit.getTrailingDbgRecords()->empty()); 1538 Exit.getTrailingDbgRecords()->eraseFromParent(); 1539 Exit.deleteTrailingDbgRecords(); 1540 1541 UseNewDbgInfoFormat = false; 1542 } 1543 1544 // What if we moveBefore end() -- there might be no debug-info there, in which 1545 // case we shouldn't crash. 1546 TEST(BasicBlockDbgInfoTest, DbgMoveToEnd) { 1547 LLVMContext C; 1548 UseNewDbgInfoFormat = true; 1549 1550 std::unique_ptr<Module> M = parseIR(C, R"( 1551 define i16 @f(i16 %a) !dbg !6 { 1552 entry: 1553 br label %exit 1554 1555 exit: 1556 ret i16 0, !dbg !11 1557 } 1558 declare void @llvm.dbg.value(metadata, metadata, metadata) #0 1559 attributes #0 = { nounwind readnone speculatable willreturn } 1560 1561 !llvm.dbg.cu = !{!0} 1562 !llvm.module.flags = !{!5} 1563 1564 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 1565 !1 = !DIFile(filename: "t.ll", directory: "/") 1566 !2 = !{} 1567 !5 = !{i32 2, !"Debug Info Version", i32 3} 1568 !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8) 1569 !7 = !DISubroutineType(types: !2) 1570 !8 = !{!9} 1571 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) 1572 !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned) 1573 !11 = !DILocation(line: 1, column: 1, scope: !6) 1574 )"); 1575 1576 Function &F = *M->getFunction("f"); 1577 BasicBlock &Entry = F.getEntryBlock(); 1578 BasicBlock &Exit = *Entry.getNextNode(); 1579 M->convertToNewDbgValues(); 1580 1581 // Move the return to the end of the entry block. 1582 Instruction *Br = Entry.getTerminator(); 1583 Instruction *Ret = Exit.getTerminator(); 1584 EXPECT_EQ(Entry.getTrailingDbgRecords(), nullptr); 1585 Ret->moveBefore(Entry, Entry.end()); 1586 Br->eraseFromParent(); 1587 1588 // There should continue to not be any debug-info anywhere. 1589 EXPECT_EQ(Entry.getTrailingDbgRecords(), nullptr); 1590 EXPECT_EQ(Exit.getTrailingDbgRecords(), nullptr); 1591 EXPECT_FALSE(Ret->hasDbgRecords()); 1592 1593 UseNewDbgInfoFormat = false; 1594 } 1595 1596 } // End anonymous namespace. 1597