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