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