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