brintos

brintos / llvm-project-archived public Read only

0
0
Text · 64.3 KiB · 7780bba Raw
1640 lines · cpp
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-exception6//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 26using namespace llvm;27 28static 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 36namespace {37 38// We can occasionally moveAfter an instruction so that it moves to the39// position that it already resides at. This is fine -- but gets complicated40// with dbg.value intrinsics. By moving an instruction, we can end up changing41// nothing but the location of debug-info intrinsics. That has to be modelled42// by DbgVariableRecords, the dbg.value replacement.43TEST(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 !1148      %b = add i16 %a, 1, !dbg !1149      call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !1150      %c = add i16 %b, 1, !dbg !1151      ret i16 0, !dbg !1152    }53    declare void @llvm.dbg.value(metadata, metadata, metadata) #054    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. Were82  // we in dbg.value form we would then have:83  //    dbg.value84  //    %b = add85  //    %c = add86  //    dbg.value87  // 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 102TEST(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 4107      tail call void @llvm.dbg.declare(metadata ptr %1, metadata !14, metadata !DIExpression()), !dbg !16108      store i32 2, ptr %1, align 4, !dbg !16109      ret void, !dbg !17110    }111 112    declare void @llvm.dbg.declare(metadata, metadata, metadata) #0113 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 152TEST(BasicBlockDbgInfoTest, DropSourceAtomOnSplit) {153  LLVMContext C;154  std::unique_ptr<Module> M = parseIR(C, R"---(155    define dso_local void @func() !dbg !10 {156      %1 = alloca i32, align 4157      ret void, !dbg !DILocation(line: 3, column: 2, scope: !10, atomGroup: 1, atomRank: 1)158    }159 160    !llvm.dbg.cu = !{!0}161    !llvm.module.flags = !{!2, !3}162 163    !0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "dummy", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)164    !1 = !DIFile(filename: "dummy", directory: "dummy")165    !2 = !{i32 7, !"Dwarf Version", i32 5}166    !3 = !{i32 2, !"Debug Info Version", i32 3}167    !10 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !13, keyInstructions: true)168    !11 = !DISubroutineType(types: !12)169    !12 = !{null}170    !13 = !{}171    !14 = !DILocalVariable(name: "a", scope: !10, file: !1, line: 2, type: !15)172    !15 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)173  )---");174  ASSERT_TRUE(M);175 176  Function *F = M->getFunction("func");177 178  // Test splitBasicBlockBefore.179  {180    BasicBlock &BB = F->back();181    // Split at `ret void`.182    BasicBlock *Before =183        BB.splitBasicBlockBefore(std::prev(BB.end(), 1), "before");184    const DebugLoc &BrToAfterDL = Before->getTerminator()->getDebugLoc();185    ASSERT_TRUE(BrToAfterDL);186    EXPECT_EQ(BrToAfterDL->getAtomGroup(), 0u);187 188    BasicBlock *After = Before->getSingleSuccessor();189    ASSERT_TRUE(After);190    const DebugLoc &OrigTerminatorDL = After->getTerminator()->getDebugLoc();191    ASSERT_TRUE(OrigTerminatorDL);192    EXPECT_EQ(OrigTerminatorDL->getAtomGroup(), 1u);193  }194 195  // Test splitBasicBlock.196  {197    BasicBlock &BB = F->back();198    // Split at `ret void`.199    BasicBlock *After = BB.splitBasicBlock(std::prev(BB.end(), 1), "before");200 201    const DebugLoc &OrigTerminatorDL = After->getTerminator()->getDebugLoc();202    ASSERT_TRUE(OrigTerminatorDL);203    EXPECT_EQ(OrigTerminatorDL->getAtomGroup(), 1u);204 205    BasicBlock *Before = After->getSinglePredecessor();206    ASSERT_TRUE(Before);207    const DebugLoc &BrToAfterDL = Before->getTerminator()->getDebugLoc();208    ASSERT_TRUE(BrToAfterDL);209    EXPECT_EQ(BrToAfterDL->getAtomGroup(), 0u);210  }211}212 213TEST(BasicBlockDbgInfoTest, MarkerOperations) {214  LLVMContext C;215  std::unique_ptr<Module> M = parseIR(C, R"(216    define i16 @f(i16 %a) !dbg !6 {217      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11218      %b = add i16 %a, 1, !dbg !11219      call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11220      ret i16 0, !dbg !11221    }222    declare void @llvm.dbg.value(metadata, metadata, metadata) #0223    attributes #0 = { nounwind readnone speculatable willreturn }224 225    !llvm.dbg.cu = !{!0}226    !llvm.module.flags = !{!5}227 228    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)229    !1 = !DIFile(filename: "t.ll", directory: "/")230    !2 = !{}231    !5 = !{i32 2, !"Debug Info Version", i32 3}232    !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)233    !7 = !DISubroutineType(types: !2)234    !8 = !{!9}235    !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)236    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)237    !11 = !DILocation(line: 1, column: 1, scope: !6)238)");239 240  // Fetch the entry block,241  BasicBlock &BB = M->getFunction("f")->getEntryBlock();242  EXPECT_EQ(BB.size(), 2u);243 244  // Fetch out our two markers,245  Instruction *Instr1 = &*BB.begin();246  Instruction *Instr2 = Instr1->getNextNode();247  DbgMarker *Marker1 = Instr1->DebugMarker;248  DbgMarker *Marker2 = Instr2->DebugMarker;249  // There's no TrailingDbgRecords marker allocated yet.250  DbgMarker *EndMarker = nullptr;251 252  // Check that the "getMarker" utilities operate as expected.253  EXPECT_EQ(BB.getMarker(Instr1->getIterator()), Marker1);254  EXPECT_EQ(BB.getMarker(Instr2->getIterator()), Marker2);255  EXPECT_EQ(BB.getNextMarker(Instr1), Marker2);256  EXPECT_EQ(BB.getNextMarker(Instr2), EndMarker); // Is nullptr.257 258  // There should be two DbgVariableRecords,259  EXPECT_EQ(Marker1->StoredDbgRecords.size(), 1u);260  EXPECT_EQ(Marker2->StoredDbgRecords.size(), 1u);261 262  // Unlink them and try to re-insert them through the basic block.263  DbgRecord *DVR1 = &*Marker1->StoredDbgRecords.begin();264  DbgRecord *DVR2 = &*Marker2->StoredDbgRecords.begin();265  DVR1->removeFromParent();266  DVR2->removeFromParent();267  EXPECT_TRUE(Marker1->StoredDbgRecords.empty());268  EXPECT_TRUE(Marker2->StoredDbgRecords.empty());269 270  // This should appear in Marker1.271  BB.insertDbgRecordBefore(DVR1, BB.begin());272  EXPECT_EQ(Marker1->StoredDbgRecords.size(), 1u);273  EXPECT_EQ(DVR1, &*Marker1->StoredDbgRecords.begin());274 275  // This should attach to Marker2.276  BB.insertDbgRecordAfter(DVR2, &*BB.begin());277  EXPECT_EQ(Marker2->StoredDbgRecords.size(), 1u);278  EXPECT_EQ(DVR2, &*Marker2->StoredDbgRecords.begin());279 280  // Now, how about removing instructions? That should cause any281  // DbgVariableRecords to "fall down".282  Instr1->removeFromParent();283  Marker1 = nullptr;284  // DbgVariableRecords should now be in Marker2.285  EXPECT_EQ(BB.size(), 1u);286  EXPECT_EQ(Marker2->StoredDbgRecords.size(), 2u);287  // They should also be in the correct order.288  SmallVector<DbgRecord *, 2> DVRs(289      llvm::make_pointer_range(Marker2->getDbgRecordRange()));290  EXPECT_EQ(DVRs[0], DVR1);291  EXPECT_EQ(DVRs[1], DVR2);292 293  // If we remove the end instruction, the DbgVariableRecords should fall down294  // into the trailing marker.295  EXPECT_EQ(BB.getTrailingDbgRecords(), nullptr);296  Instr2->removeFromParent();297  EXPECT_TRUE(BB.empty());298  EndMarker = BB.getTrailingDbgRecords();299  ASSERT_NE(EndMarker, nullptr);300  EXPECT_EQ(EndMarker->StoredDbgRecords.size(), 2u);301  // Again, these should arrive in the correct order.302 303  DVRs.clear();304  for (DbgRecord &DVR : EndMarker->getDbgRecordRange())305    DVRs.push_back(&DVR);306  EXPECT_EQ(DVRs[0], DVR1);307  EXPECT_EQ(DVRs[1], DVR2);308 309  // Inserting a normal instruction at the beginning: shouldn't dislodge the310  // DbgVariableRecords. It's intended to not go at the start.311  Instr1->insertBefore(BB, BB.begin());312  EXPECT_EQ(EndMarker->StoredDbgRecords.size(), 2u);313  Instr1->removeFromParent();314 315  // Inserting at end(): should dislodge the DbgVariableRecords, if they were316  // dbg.values then they would sit "above" the new instruction.317  Instr1->insertBefore(BB, BB.end());318  EXPECT_EQ(Instr1->DebugMarker->StoredDbgRecords.size(), 2u);319  // We should de-allocate the trailing marker when something is inserted320  // at end().321  EXPECT_EQ(BB.getTrailingDbgRecords(), nullptr);322 323  // Remove Instr1: now the DbgVariableRecords will fall down again,324  Instr1->removeFromParent();325  EndMarker = BB.getTrailingDbgRecords();326  EXPECT_EQ(EndMarker->StoredDbgRecords.size(), 2u);327 328  // Inserting a terminator, however it's intended, should dislodge the329  // trailing DbgVariableRecords, as it's the clear intention of the caller that330  // this be the final instr in the block, and DbgVariableRecords aren't allowed331  // to live off the end forever.332  Instr2->insertBefore(BB, BB.begin());333  EXPECT_EQ(Instr2->DebugMarker->StoredDbgRecords.size(), 2u);334  EXPECT_EQ(BB.getTrailingDbgRecords(), nullptr);335 336  // Teardown,337  Instr1->insertBefore(BB, BB.begin());338}339 340TEST(BasicBlockDbgInfoTest, HeadBitOperations) {341  LLVMContext C;342  std::unique_ptr<Module> M = parseIR(C, R"(343    define i16 @f(i16 %a) !dbg !6 {344      %b = add i16 %a, 1, !dbg !11345      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11346      %c = add i16 %a, 1, !dbg !11347      %d = add i16 %a, 1, !dbg !11348      ret i16 0, !dbg !11349    }350    declare void @llvm.dbg.value(metadata, metadata, metadata) #0351    attributes #0 = { nounwind readnone speculatable willreturn }352 353    !llvm.dbg.cu = !{!0}354    !llvm.module.flags = !{!5}355 356    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)357    !1 = !DIFile(filename: "t.ll", directory: "/")358    !2 = !{}359    !5 = !{i32 2, !"Debug Info Version", i32 3}360    !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)361    !7 = !DISubroutineType(types: !2)362    !8 = !{!9}363    !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)364    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)365    !11 = !DILocation(line: 1, column: 1, scope: !6)366)");367 368  // Test that the movement of debug-data when using moveBefore etc and369  // insertBefore etc are governed by the "head" bit of iterators.370  BasicBlock &BB = M->getFunction("f")->getEntryBlock();371 372  // Test that the head bit behaves as expected: it should be set when the373  // code wants the _start_ of the block, but not otherwise.374  EXPECT_TRUE(BB.getFirstInsertionPt().getHeadBit());375  BasicBlock::iterator BeginIt = BB.begin();376  EXPECT_TRUE(BeginIt.getHeadBit());377  // If you launder the instruction pointer through dereferencing and then378  // get the iterator again with getIterator, the head bit is lost. This is379  // deliberate: if you're calling getIterator, then you're requesting an380  // iterator for the position of _this_ instruction, not "the start of this381  // block".382  BasicBlock::iterator BeginIt2 = BeginIt->getIterator();383  EXPECT_FALSE(BeginIt2.getHeadBit());384 385  // Fetch some instruction pointers.386  Instruction *BInst = &*BeginIt;387  Instruction *CInst = BInst->getNextNode();388  Instruction *DInst = CInst->getNextNode();389  // CInst should have debug-info.390  ASSERT_TRUE(CInst->DebugMarker);391  EXPECT_FALSE(CInst->DebugMarker->StoredDbgRecords.empty());392 393  // If we move "c" to the start of the block, just normally, then the394  // DbgVariableRecords should fall down to "d".395  CInst->moveBefore(BB, BeginIt2);396  EXPECT_TRUE(!CInst->DebugMarker ||397              CInst->DebugMarker->StoredDbgRecords.empty());398  ASSERT_TRUE(DInst->DebugMarker);399  EXPECT_FALSE(DInst->DebugMarker->StoredDbgRecords.empty());400 401  // Wheras if we move D to the start of the block with moveBeforePreserving,402  // the DbgVariableRecords should move with it.403  DInst->moveBeforePreserving(BB, BB.begin());404  EXPECT_FALSE(DInst->DebugMarker->StoredDbgRecords.empty());405  EXPECT_EQ(&*BB.begin(), DInst);406 407  // Similarly, moveAfterPreserving "D" to "C" should move DbgVariableRecords408  // with "D".409  DInst->moveAfterPreserving(CInst);410  EXPECT_FALSE(DInst->DebugMarker->StoredDbgRecords.empty());411 412  // (move back to the start...)413  DInst->moveBeforePreserving(BB, BB.begin());414 415  // Current order of insts: "D -> C -> B -> Ret". DbgVariableRecords on "D".416  // If we move "C" to the beginning of the block, it should go before the417  // DbgVariableRecords. They'll stay on "D".418  CInst->moveBefore(BB, BB.begin());419  EXPECT_TRUE(!CInst->DebugMarker ||420              CInst->DebugMarker->StoredDbgRecords.empty());421  EXPECT_FALSE(DInst->DebugMarker->StoredDbgRecords.empty());422  EXPECT_EQ(&*BB.begin(), CInst);423  EXPECT_EQ(CInst->getNextNode(), DInst);424 425  // Move back.426  CInst->moveBefore(BInst->getIterator());427  EXPECT_EQ(&*BB.begin(), DInst);428 429  // Current order of insts: "D -> C -> B -> Ret". DbgVariableRecords on "D".430  // Now move CInst to the position of DInst, but using getIterator instead of431  // BasicBlock::begin. This signals that we want the "C" instruction to be432  // immediately before "D", with any DbgVariableRecords on "D" now moving to433  // "C". It's the equivalent of moving an instruction to the position between a434  // run of dbg.values and the next instruction.435  CInst->moveBefore(BB, DInst->getIterator());436  // CInst gains the DbgVariableRecords.437  EXPECT_TRUE(!DInst->DebugMarker ||438              DInst->DebugMarker->StoredDbgRecords.empty());439  EXPECT_FALSE(CInst->DebugMarker->StoredDbgRecords.empty());440  EXPECT_EQ(&*BB.begin(), CInst);441}442 443TEST(BasicBlockDbgInfoTest, InstrDbgAccess) {444  LLVMContext C;445  std::unique_ptr<Module> M = parseIR(C, R"(446    define i16 @f(i16 %a) !dbg !6 {447      %b = add i16 %a, 1, !dbg !11448      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11449      %c = add i16 %a, 1, !dbg !11450      %d = add i16 %a, 1, !dbg !11451      ret i16 0, !dbg !11452    }453    declare void @llvm.dbg.value(metadata, metadata, metadata) #0454    attributes #0 = { nounwind readnone speculatable willreturn }455 456    !llvm.dbg.cu = !{!0}457    !llvm.module.flags = !{!5}458 459    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)460    !1 = !DIFile(filename: "t.ll", directory: "/")461    !2 = !{}462    !5 = !{i32 2, !"Debug Info Version", i32 3}463    !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)464    !7 = !DISubroutineType(types: !2)465    !8 = !{!9}466    !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)467    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)468    !11 = !DILocation(line: 1, column: 1, scope: !6)469)");470 471  // Check that DbgVariableRecords can be accessed from Instructions without472  // digging into the depths of DbgMarkers.473  BasicBlock &BB = M->getFunction("f")->getEntryBlock();474 475  Instruction *BInst = &*BB.begin();476  Instruction *CInst = BInst->getNextNode();477  Instruction *DInst = CInst->getNextNode();478 479  ASSERT_FALSE(BInst->DebugMarker);480  ASSERT_TRUE(CInst->DebugMarker);481  ASSERT_EQ(CInst->DebugMarker->StoredDbgRecords.size(), 1u);482  DbgRecord *DVR1 = &*CInst->DebugMarker->StoredDbgRecords.begin();483  ASSERT_TRUE(DVR1);484  EXPECT_FALSE(BInst->hasDbgRecords());485 486  // Clone DbgVariableRecords from one inst to another. Other arguments to clone487  // are tested in DbgMarker test.488  auto Range1 = BInst->cloneDebugInfoFrom(CInst);489  EXPECT_EQ(BInst->DebugMarker->StoredDbgRecords.size(), 1u);490  DbgRecord *DVR2 = &*BInst->DebugMarker->StoredDbgRecords.begin();491  EXPECT_EQ(std::distance(Range1.begin(), Range1.end()), 1u);492  EXPECT_EQ(&*Range1.begin(), DVR2);493  EXPECT_NE(DVR1, DVR2);494 495  // We should be able to get a range over exactly the same information.496  auto Range2 = BInst->getDbgRecordRange();497  EXPECT_EQ(Range1.begin(), Range2.begin());498  EXPECT_EQ(Range1.end(), Range2.end());499 500  // We should be able to query if there are DbgVariableRecords,501  EXPECT_TRUE(BInst->hasDbgRecords());502  EXPECT_TRUE(CInst->hasDbgRecords());503  EXPECT_FALSE(DInst->hasDbgRecords());504 505  // Dropping should be easy,506  BInst->dropDbgRecords();507  EXPECT_FALSE(BInst->hasDbgRecords());508  EXPECT_EQ(BInst->DebugMarker->StoredDbgRecords.size(), 0u);509 510  // And we should be able to drop individual DbgVariableRecords.511  CInst->dropOneDbgRecord(DVR1);512  EXPECT_FALSE(CInst->hasDbgRecords());513  EXPECT_EQ(CInst->DebugMarker->StoredDbgRecords.size(), 0u);514}515 516/* Let's recall the big illustration from BasicBlock::spliceDebugInfo:517 518                                               Dest519                                                 |520   this-block:    A----A----A                ====A----A----A----A---A---A521    Src-block                ++++B---B---B---B:::C522                                 |               |523                                First           Last524 525  in all it's glory. Depending on the bit-configurations for the iterator head526  / tail bits on the three named iterators, there are eight ways for a splice to527  occur. To save the amount of thinking needed to pack this into one unit test,528  just test the same IR eight times with difference splices. The IR shall be529  thus:530 531    define i16 @f(i16 %a) !dbg !6 {532    entry:533      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11534      %b = add i16 %a, 1, !dbg !11535      call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11536      br label %exit, !dbg !11537 538    exit:539      call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11540      %c = add i16 %b, 1, !dbg !11541      ret i16 0, !dbg !11542    }543 544  The iterators will be:545    Dest: exit block, "c" instruction.546    First: entry block, "b" instruction.547    Last: entry block, branch instruction.548 549  The numbered configurations will be:550 551       |    Dest-Head   |   First-Head   |   Last-tail552   ----+----------------+----------------+------------553    0  |      false     |     false      |     false554    1  |      true      |     false      |     false555    2  |      false     |     true       |     false556    3  |      true      |     true       |     false557    4  |      false     |     false      |     true558    5  |      true      |     false      |     true559    6  |      false     |     true       |     true560    7  |      true      |     true       |     true561 562  Each numbered test scenario will also have a short explanation indicating what563  this bit configuration represents.564*/565 566static const std::string SpliceTestIR = R"(567    define i16 @f(i16 %a) !dbg !6 {568      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11569      %b = add i16 %a, 1, !dbg !11570      call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11571      br label %exit, !dbg !11572 573    exit:574      call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11575      %c = add i16 %b, 1, !dbg !11576      ret i16 0, !dbg !11577    }578    declare void @llvm.dbg.value(metadata, metadata, metadata) #0579    attributes #0 = { nounwind readnone speculatable willreturn }580 581    !llvm.dbg.cu = !{!0}582    !llvm.module.flags = !{!5}583 584    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)585    !1 = !DIFile(filename: "t.ll", directory: "/")586    !2 = !{}587    !5 = !{i32 2, !"Debug Info Version", i32 3}588    !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)589    !7 = !DISubroutineType(types: !2)590    !8 = !{!9}591    !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)592    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)593    !11 = !DILocation(line: 1, column: 1, scope: !6)594)";595 596class DbgSpliceTest : public ::testing::Test {597protected:598  LLVMContext C;599  std::unique_ptr<Module> M;600  BasicBlock *BBEntry, *BBExit;601  BasicBlock::iterator Dest, First, Last;602  Instruction *BInst, *Branch, *CInst;603  DbgVariableRecord *DVRA, *DVRB, *DVRConst;604 605  void SetUp() override {606    M = parseIR(C, SpliceTestIR.c_str());607 608    BBEntry = &M->getFunction("f")->getEntryBlock();609    BBExit = BBEntry->getNextNode();610 611    Dest = BBExit->begin();612    First = BBEntry->begin();613    Last = BBEntry->getTerminator()->getIterator();614    BInst = &*First;615    Branch = &*Last;616    CInst = &*Dest;617 618    DVRA =619        cast<DbgVariableRecord>(&*BInst->DebugMarker->StoredDbgRecords.begin());620    DVRB = cast<DbgVariableRecord>(621        &*Branch->DebugMarker->StoredDbgRecords.begin());622    DVRConst =623        cast<DbgVariableRecord>(&*CInst->DebugMarker->StoredDbgRecords.begin());624  }625 626  bool InstContainsDbgVariableRecord(Instruction *I, DbgVariableRecord *DVR) {627    for (DbgRecord &D : I->getDbgRecordRange()) {628      if (&D == DVR) {629        // Confirm too that the links between the records are correct.630        EXPECT_EQ(DVR->Marker, I->DebugMarker);631        EXPECT_EQ(I->DebugMarker->MarkedInstr, I);632        return true;633      }634    }635    return false;636  }637 638  bool CheckDVROrder(Instruction *I,639                     SmallVector<DbgVariableRecord *> CheckVals) {640    SmallVector<DbgRecord *> Vals(641        llvm::make_pointer_range(I->getDbgRecordRange()));642 643    EXPECT_EQ(Vals.size(), CheckVals.size());644    if (Vals.size() != CheckVals.size())645      return false;646 647    for (unsigned int I = 0; I < Vals.size(); ++I) {648      EXPECT_EQ(Vals[I], CheckVals[I]);649      // Provide another expectation failure to let us localise what goes wrong,650      // by returning a flag to the caller.651      if (Vals[I] != CheckVals[I])652        return false;653    }654    return true;655  }656};657 658TEST_F(DbgSpliceTest, DbgSpliceTest0) {659  Dest.setHeadBit(false);660  First.setHeadBit(false);661  Last.setTailBit(false);662 663  /*664        define i16 @f(i16 %a) !dbg !6 {665BBEntry entry:666DVRA      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata667!DIExpression()), !dbg !11 First     %b = add i16 %a, 1, !dbg !11 DVRB      call668void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()),669!dbg !11 Last      br label %exit, !dbg !11670 671BBExit  exit:672DVRConst  call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata673!DIExpression()), !dbg !11 Dest      %c = add i16 %b, 1, !dbg !11 ret i16 0,674!dbg !11675        }676 677    Splice from First, not including leading dbg.value, to Last, including the678    trailing dbg.value. Place at Dest, between the constant dbg.value and %c.679    %b, and the following dbg.value, should move, to:680 681        define i16 @f(i16 %a) !dbg !6 {682BBEntry entry:683DVRA      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata684!DIExpression()), !dbg !11 Last      br label %exit, !dbg !11685 686BBExit  exit:687DVRConst  call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata688!DIExpression()), !dbg !11 First     %b = add i16 %a, 1, !dbg !11 DVRB      call689void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()),690!dbg !11 Dest      %c = add i16 %b, 1, !dbg !11 ret i16 0, !dbg !11691        }692 693 694  */695  BBExit->splice(Dest, BBEntry, First, Last);696  EXPECT_EQ(BInst->getParent(), BBExit);697  EXPECT_EQ(CInst->getParent(), BBExit);698  EXPECT_EQ(Branch->getParent(), BBEntry);699 700  // DVRB: should be on Dest, in exit block.701  EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRB));702 703  // DVRA, should have "fallen" onto the branch, remained in entry block.704  EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRA));705 706  // DVRConst should be on the moved %b instruction.707  EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRConst));708}709 710TEST_F(DbgSpliceTest, DbgSpliceTest1) {711  Dest.setHeadBit(true);712  First.setHeadBit(false);713  Last.setTailBit(false);714 715  /*716        define i16 @f(i16 %a) !dbg !6 {717BBEntry entry:718DVRA      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata719!DIExpression()), !dbg !11 First     %b = add i16 %a, 1, !dbg !11 DVRB      call720void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()),721!dbg !11 Last      br label %exit, !dbg !11722 723BBExit  exit:724DVRConst  call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata725!DIExpression()), !dbg !11 Dest      %c = add i16 %b, 1, !dbg !11 ret i16 0,726!dbg !11727        }728 729    Splice from First, not including leading dbg.value, to Last, including the730    trailing dbg.value. Place at the head of Dest, i.e. at the very start of731    BBExit, before any debug-info there. Becomes:732 733        define i16 @f(i16 %a) !dbg !6 {734BBEntry entry:735DVRA      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata736!DIExpression()), !dbg !11 Last      br label %exit, !dbg !11737 738BBExit  exit:739First     %b = add i16 %a, 1, !dbg !11740DVRB      call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata741!DIExpression()), !dbg !11 DVRConst  call void @llvm.dbg.value(metadata i16 0,742metadata !9, metadata !DIExpression()), !dbg !11 Dest      %c = add i16 %b, 1,743!dbg !11 ret i16 0, !dbg !11744        }745 746 747  */748  BBExit->splice(Dest, BBEntry, First, Last);749  EXPECT_EQ(BInst->getParent(), BBExit);750  EXPECT_EQ(CInst->getParent(), BBExit);751  EXPECT_EQ(Branch->getParent(), BBEntry);752 753  // DVRB: should be on CInst, in exit block.754  EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRB));755 756  // DVRA, should have "fallen" onto the branch, remained in entry block.757  EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRA));758 759  // DVRConst should be behind / after the moved instructions, remain on CInst.760  EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst));761 762  // Order of DVRB and DVRConst should be thus:763  EXPECT_TRUE(CheckDVROrder(CInst, {DVRB, DVRConst}));764}765 766TEST_F(DbgSpliceTest, DbgSpliceTest2) {767  Dest.setHeadBit(false);768  First.setHeadBit(true);769  Last.setTailBit(false);770 771  /*772        define i16 @f(i16 %a) !dbg !6 {773BBEntry entry:774DVRA      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata775!DIExpression()), !dbg !11 First     %b = add i16 %a, 1, !dbg !11 DVRB      call776void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()),777!dbg !11 Last      br label %exit, !dbg !11778 779BBExit  exit:780DVRConst  call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata781!DIExpression()), !dbg !11 Dest      %c = add i16 %b, 1, !dbg !11 ret i16 0,782!dbg !11783        }784 785    Splice from head of First, which includes the leading dbg.value, to Last,786    including the trailing dbg.value. Place in front of Dest, but after any787    debug-info there. Becomes:788 789        define i16 @f(i16 %a) !dbg !6 {790BBEntry entry:791Last      br label %exit, !dbg !11792 793BBExit  exit:794DVRConst  call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata795!DIExpression()), !dbg !11 DVRA      call void @llvm.dbg.value(metadata i16 %a,796metadata !9, metadata !DIExpression()), !dbg !11 First     %b = add i16 %a, 1,797!dbg !11 DVRB      call void @llvm.dbg.value(metadata i16 %b, metadata !9,798metadata !DIExpression()), !dbg !11 Dest      %c = add i16 %b, 1, !dbg !11 ret799i16 0, !dbg !11800        }801 802 803  */804  BBExit->splice(Dest, BBEntry, First, Last);805  EXPECT_EQ(BInst->getParent(), BBExit);806  EXPECT_EQ(CInst->getParent(), BBExit);807 808  // DVRB: should be on CInst, in exit block.809  EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRB));810 811  // DVRA, should have transferred with the spliced instructions, remains on812  // the "b" inst.813  EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRA));814 815  // DVRConst should be ahead of the moved instructions, ahead of BInst.816  EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRConst));817 818  // Order of DVRA and DVRConst should be thus:819  EXPECT_TRUE(CheckDVROrder(BInst, {DVRConst, DVRA}));820}821 822TEST_F(DbgSpliceTest, DbgSpliceTest3) {823  Dest.setHeadBit(true);824  First.setHeadBit(true);825  Last.setTailBit(false);826 827  /*828        define i16 @f(i16 %a) !dbg !6 {829BBEntry entry:830DVRA      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata831!DIExpression()), !dbg !11 First     %b = add i16 %a, 1, !dbg !11 DVRB      call832void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()),833!dbg !11 Last      br label %exit, !dbg !11834 835BBExit  exit:836DVRConst  call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata837!DIExpression()), !dbg !11 Dest      %c = add i16 %b, 1, !dbg !11 ret i16 0,838!dbg !11839        }840 841    Splice from head of First, which includes the leading dbg.value, to Last,842    including the trailing dbg.value. Place at head of Dest, before any843    debug-info there. Becomes:844 845        define i16 @f(i16 %a) !dbg !6 {846BBEntry entry:847Last      br label %exit, !dbg !11848 849BBExit  exit:850DVRA      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata851!DIExpression()), !dbg !11 First     %b = add i16 %a, 1, !dbg !11 DVRB      call852void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()),853!dbg !11 DVRConst  call void @llvm.dbg.value(metadata i16 0, metadata !9,854metadata !DIExpression()), !dbg !11 Dest      %c = add i16 %b, 1, !dbg !11 ret855i16 0, !dbg !11856        }857 858  */859  BBExit->splice(Dest, BBEntry, First, Last);860  EXPECT_EQ(BInst->getParent(), BBExit);861  EXPECT_EQ(CInst->getParent(), BBExit);862 863  // DVRB: should be on CInst, in exit block.864  EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRB));865 866  // DVRA, should have transferred with the spliced instructions, remains on867  // the "b" inst.868  EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRA));869 870  // DVRConst should be behind the moved instructions, ahead of CInst.871  EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst));872 873  // Order of DVRB and DVRConst should be thus:874  EXPECT_TRUE(CheckDVROrder(CInst, {DVRB, DVRConst}));875}876 877TEST_F(DbgSpliceTest, DbgSpliceTest4) {878  Dest.setHeadBit(false);879  First.setHeadBit(false);880  Last.setTailBit(true);881 882  /*883        define i16 @f(i16 %a) !dbg !6 {884BBEntry entry:885DVRA      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata886!DIExpression()), !dbg !11 First     %b = add i16 %a, 1, !dbg !11 DVRB      call887void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()),888!dbg !11 Last      br label %exit, !dbg !11889 890BBExit  exit:891DVRConst  call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata892!DIExpression()), !dbg !11 Dest      %c = add i16 %b, 1, !dbg !11 ret i16 0,893!dbg !11894        }895 896    Splice from First, not including the leading dbg.value, to Last, but NOT897    including the trailing dbg.value because the tail bit is set. Place at Dest,898    after any debug-info there. Becomes:899 900        define i16 @f(i16 %a) !dbg !6 {901BBEntry entry:902DVRA      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata903!DIExpression()), !dbg !11 DVRB      call void @llvm.dbg.value(metadata i16 %b,904metadata !9, metadata !DIExpression()), !dbg !11 Last      br label %exit, !dbg905!11906 907BBExit  exit:908DVRConst  call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata909!DIExpression()), !dbg !11 First     %b = add i16 %a, 1, !dbg !11 Dest      %c =910add i16 %b, 1, !dbg !11 ret i16 0, !dbg !11911        }912 913  */914  BBExit->splice(Dest, BBEntry, First, Last);915  EXPECT_EQ(BInst->getParent(), BBExit);916  EXPECT_EQ(CInst->getParent(), BBExit);917  EXPECT_EQ(Branch->getParent(), BBEntry);918 919  // DVRB: should be on Branch as before, remain in entry block.920  EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB));921 922  // DVRA, should have remained in entry block, falls onto Branch inst.923  EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRA));924 925  // DVRConst should be ahead of the moved instructions, BInst.926  EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRConst));927 928  // Order of DVRA and DVRA should be thus:929  EXPECT_TRUE(CheckDVROrder(Branch, {DVRA, DVRB}));930}931 932TEST_F(DbgSpliceTest, DbgSpliceTest5) {933  Dest.setHeadBit(true);934  First.setHeadBit(false);935  Last.setTailBit(true);936 937  /*938        define i16 @f(i16 %a) !dbg !6 {939BBEntry entry:940DVRA      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata941!DIExpression()), !dbg !11 First     %b = add i16 %a, 1, !dbg !11 DVRB      call942void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()),943!dbg !11 Last      br label %exit, !dbg !11944 945BBExit  exit:946DVRConst  call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata947!DIExpression()), !dbg !11 Dest      %c = add i16 %b, 1, !dbg !11 ret i16 0,948!dbg !11949        }950 951    Splice from First, not including the leading dbg.value, to Last, but NOT952    including the trailing dbg.value because the tail bit is set. Place at head953    of Dest, before any debug-info there. Becomes:954 955        define i16 @f(i16 %a) !dbg !6 {956BBEntry entry:957DVRA      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata958!DIExpression()), !dbg !11 DVRB      call void @llvm.dbg.value(metadata i16 %b,959metadata !9, metadata !DIExpression()), !dbg !11 Last      br label %exit, !dbg960!11961 962BBExit  exit:963First     %b = add i16 %a, 1, !dbg !11964DVRConst  call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata965!DIExpression()), !dbg !11 Dest      %c = add i16 %b, 1, !dbg !11 ret i16 0,966!dbg !11967        }968 969  */970  BBExit->splice(Dest, BBEntry, First, Last);971  EXPECT_EQ(BInst->getParent(), BBExit);972  EXPECT_EQ(CInst->getParent(), BBExit);973  EXPECT_EQ(Branch->getParent(), BBEntry);974 975  // DVRB: should be on Branch as before, remain in entry block.976  EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB));977 978  // DVRA, should have remained in entry block, falls onto Branch inst.979  EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRA));980 981  // DVRConst should be behind of the moved instructions, on CInst.982  EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst));983 984  // Order of DVRA and DVRB should be thus:985  EXPECT_TRUE(CheckDVROrder(Branch, {DVRA, DVRB}));986}987 988TEST_F(DbgSpliceTest, DbgSpliceTest6) {989  Dest.setHeadBit(false);990  First.setHeadBit(true);991  Last.setTailBit(true);992 993  /*994        define i16 @f(i16 %a) !dbg !6 {995BBEntry entry:996DVRA      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata997!DIExpression()), !dbg !11 First     %b = add i16 %a, 1, !dbg !11 DVRB      call998void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()),999!dbg !11 Last      br label %exit, !dbg !111000 1001BBExit  exit:1002DVRConst  call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata1003!DIExpression()), !dbg !11 Dest      %c = add i16 %b, 1, !dbg !11 ret i16 0,1004!dbg !111005        }1006 1007    Splice from First, including the leading dbg.value, to Last, but NOT1008    including the trailing dbg.value because the tail bit is set. Place at Dest,1009    after any debug-info there. Becomes:1010 1011        define i16 @f(i16 %a) !dbg !6 {1012BBEntry entry:1013DVRB      call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata1014!DIExpression()), !dbg !11 Last      br label %exit, !dbg !111015 1016BBExit  exit:1017DVRConst  call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata1018!DIExpression()), !dbg !11 DVRA      call void @llvm.dbg.value(metadata i16 %a,1019metadata !9, metadata !DIExpression()), !dbg !11 First     %b = add i16 %a, 1,1020!dbg !11 Dest      %c = add i16 %b, 1, !dbg !11 ret i16 0, !dbg !111021        }1022 1023  */1024  BBExit->splice(Dest, BBEntry, First, Last);1025  EXPECT_EQ(BInst->getParent(), BBExit);1026  EXPECT_EQ(CInst->getParent(), BBExit);1027  EXPECT_EQ(Branch->getParent(), BBEntry);1028 1029  // DVRB: should be on Branch as before, remain in entry block.1030  EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB));1031 1032  // DVRA, should have transferred to BBExit, on B inst.1033  EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRA));1034 1035  // DVRConst should be ahead of the moved instructions, on BInst.1036  EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRConst));1037 1038  // Order of DVRA and DVRConst should be thus:1039  EXPECT_TRUE(CheckDVROrder(BInst, {DVRConst, DVRA}));1040}1041 1042TEST_F(DbgSpliceTest, DbgSpliceTest7) {1043  Dest.setHeadBit(true);1044  First.setHeadBit(true);1045  Last.setTailBit(true);1046 1047  /*1048        define i16 @f(i16 %a) !dbg !6 {1049BBEntry entry:1050DVRA      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata1051!DIExpression()), !dbg !11 First     %b = add i16 %a, 1, !dbg !11 DVRB      call1052void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()),1053!dbg !11 Last      br label %exit, !dbg !111054 1055BBExit  exit:1056DVRConst  call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata1057!DIExpression()), !dbg !11 Dest      %c = add i16 %b, 1, !dbg !11 ret i16 0,1058!dbg !111059        }1060 1061    Splice from First, including the leading dbg.value, to Last, but NOT1062    including the trailing dbg.value because the tail bit is set. Place at head1063    of Dest, before any debug-info there. Becomes:1064 1065        define i16 @f(i16 %a) !dbg !6 {1066BBEntry entry:1067DVRB      call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata1068!DIExpression()), !dbg !11 Last      br label %exit, !dbg !111069 1070BBExit  exit:1071DVRA      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata1072!DIExpression()), !dbg !11 First     %b = add i16 %a, 1, !dbg !11 DVRConst  call1073void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()),1074!dbg !11 Dest      %c = add i16 %b, 1, !dbg !11 ret i16 0, !dbg !111075        }1076 1077  */1078  BBExit->splice(Dest, BBEntry, First, Last);1079  EXPECT_EQ(BInst->getParent(), BBExit);1080  EXPECT_EQ(CInst->getParent(), BBExit);1081  EXPECT_EQ(Branch->getParent(), BBEntry);1082 1083  // DVRB: should be on Branch as before, remain in entry block.1084  EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB));1085 1086  // DVRA, should have transferred to BBExit, on B inst.1087  EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRA));1088 1089  // DVRConst should be after of the moved instructions, on CInst.1090  EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst));1091}1092 1093// But wait, there's more! What if you splice a range that is empty, but1094// implicitly contains debug-info? In the dbg.value design for debug-info,1095// this would be an explicit range, but in DbgVariableRecord debug-info, it1096// isn't. Check that if we try to do that, with differing head-bit values, that1097// DbgVariableRecords are transferred.1098// Test with empty transfers to Dest, with head bit set and not set.1099 1100TEST_F(DbgSpliceTest, DbgSpliceEmpty0) {1101  Dest.setHeadBit(false);1102  First.setHeadBit(false);1103  Last.setHeadBit(false);1104  /*1105        define i16 @f(i16 %a) !dbg !6 {1106BBEntry entry:1107DVRA      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata1108!DIExpression()), !dbg !11 First     %b = add i16 %a, 1, !dbg !11 DVRB      call1109void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()),1110!dbg !11 Last      br label %exit, !dbg !111111 1112BBExit  exit:1113DVRConst  call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata1114!DIExpression()), !dbg !11 Dest      %c = add i16 %b, 1, !dbg !11 ret i16 0,1115!dbg !111116        }1117 1118    Splice from BBEntry.getFirstInsertionPt to First -- this implicitly is a1119    splice of DVRA, but the iterators are pointing at the same instruction. The1120    only difference is the setting of the head bit. Becomes;1121 1122        define i16 @f(i16 %a) !dbg !6 {1123First     %b = add i16 %a, 1, !dbg !111124DVRB      call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata1125!DIExpression()), !dbg !11 Last      br label %exit, !dbg !111126 1127BBExit  exit:1128DVRConst  call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata1129!DIExpression()), !dbg !11 DVRA      call void @llvm.dbg.value(metadata i16 %a,1130metadata !9, metadata !DIExpression()), !dbg !11 Dest      %c = add i16 %b, 1,1131!dbg !11 ret i16 0, !dbg !111132        }1133 1134  */1135  BBExit->splice(Dest, BBEntry, BBEntry->getFirstInsertionPt(), First);1136  EXPECT_EQ(BInst->getParent(), BBEntry);1137  EXPECT_EQ(CInst->getParent(), BBExit);1138  EXPECT_EQ(Branch->getParent(), BBEntry);1139 1140  // DVRB: should be on Branch as before, remain in entry block.1141  EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB));1142 1143  // DVRA, should have transferred to BBExit, on C inst.1144  EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRA));1145 1146  // DVRConst should be ahead of the moved DbgVariableRecord, on CInst.1147  EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst));1148 1149  // Order of DVRA and DVRConst should be thus:1150  EXPECT_TRUE(CheckDVROrder(CInst, {DVRConst, DVRA}));1151}1152 1153TEST_F(DbgSpliceTest, DbgSpliceEmpty1) {1154  Dest.setHeadBit(true);1155  First.setHeadBit(false);1156  Last.setHeadBit(false);1157  /*1158        define i16 @f(i16 %a) !dbg !6 {1159BBEntry entry:1160DVRA      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata1161!DIExpression()), !dbg !11 First     %b = add i16 %a, 1, !dbg !11 DVRB      call1162void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()),1163!dbg !11 Last      br label %exit, !dbg !111164 1165BBExit  exit:1166DVRConst  call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata1167!DIExpression()), !dbg !11 Dest      %c = add i16 %b, 1, !dbg !11 ret i16 0,1168!dbg !111169        }1170 1171    Splice from BBEntry.getFirstInsertionPt to First -- this implicitly is a1172    splice of DVRA, but the iterators are pointing at the same instruction. The1173    only difference is the setting of the head bit. Insert at head of Dest,1174    i.e. before DVRConst. Becomes;1175 1176        define i16 @f(i16 %a) !dbg !6 {1177First     %b = add i16 %a, 1, !dbg !111178DVRB      call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata1179!DIExpression()), !dbg !11 Last      br label %exit, !dbg !111180 1181BBExit  exit:1182DVRA      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata1183!DIExpression()), !dbg !11 DVRConst  call void @llvm.dbg.value(metadata i16 0,1184metadata !9, metadata !DIExpression()), !dbg !11 Dest      %c = add i16 %b, 1,1185!dbg !11 ret i16 0, !dbg !111186        }1187 1188  */1189  BBExit->splice(Dest, BBEntry, BBEntry->getFirstInsertionPt(), First);1190  EXPECT_EQ(BInst->getParent(), BBEntry);1191  EXPECT_EQ(CInst->getParent(), BBExit);1192  EXPECT_EQ(Branch->getParent(), BBEntry);1193 1194  // DVRB: should be on Branch as before, remain in entry block.1195  EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB));1196 1197  // DVRA, should have transferred to BBExit, on C inst.1198  EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRA));1199 1200  // DVRConst should be ahead of the moved DbgVariableRecord, on CInst.1201  EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst));1202 1203  // Order of DVRA and DVRConst should be thus:1204  EXPECT_TRUE(CheckDVROrder(CInst, {DVRA, DVRConst}));1205}1206 1207// If we splice new instructions into a block with trailing DbgVariableRecords,1208// then the trailing DbgVariableRecords should get flushed back out.1209TEST(BasicBlockDbgInfoTest, DbgSpliceTrailing) {1210  LLVMContext C;1211  std::unique_ptr<Module> M = parseIR(C, R"(1212    define i16 @f(i16 %a) !dbg !6 {1213    entry:1214      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !111215      br label %exit1216 1217    exit:1218      %b = add i16 %a, 1, !dbg !111219      ret i16 0, !dbg !111220    }1221    declare void @llvm.dbg.value(metadata, metadata, metadata) #01222    attributes #0 = { nounwind readnone speculatable willreturn }1223 1224    !llvm.dbg.cu = !{!0}1225    !llvm.module.flags = !{!5}1226 1227    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)1228    !1 = !DIFile(filename: "t.ll", directory: "/")1229    !2 = !{}1230    !5 = !{i32 2, !"Debug Info Version", i32 3}1231    !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)1232    !7 = !DISubroutineType(types: !2)1233    !8 = !{!9}1234    !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)1235    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)1236    !11 = !DILocation(line: 1, column: 1, scope: !6)1237)");1238 1239  BasicBlock &Entry = M->getFunction("f")->getEntryBlock();1240  BasicBlock &Exit = *Entry.getNextNode();1241 1242  // Begin by forcing entry block to have dangling DbgVariableRecord.1243  Entry.getTerminator()->eraseFromParent();1244  ASSERT_NE(Entry.getTrailingDbgRecords(), nullptr);1245  EXPECT_TRUE(Entry.empty());1246 1247  // Now transfer the entire contents of the exit block into the entry.1248  Entry.splice(Entry.end(), &Exit, Exit.begin(), Exit.end());1249 1250  // The trailing DbgVariableRecord should have been placed at the front of1251  // what's been spliced in.1252  Instruction *BInst = &*Entry.begin();1253  ASSERT_TRUE(BInst->DebugMarker);1254  EXPECT_EQ(BInst->DebugMarker->StoredDbgRecords.size(), 1u);1255}1256 1257// When we remove instructions from the program, adjacent DbgVariableRecords1258// coalesce together into one DbgMarker. In "old" dbg.value mode you could1259// re-insert the removed instruction back into the middle of a sequence of1260// dbg.values. Test that this can be replicated correctly by DbgVariableRecords1261TEST(BasicBlockDbgInfoTest, RemoveInstAndReinsert) {1262  LLVMContext C;1263  std::unique_ptr<Module> M = parseIR(C, R"(1264    define i16 @f(i16 %a) !dbg !6 {1265    entry:1266      %qux = sub i16 %a, 01267      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !111268      %foo = add i16 %a, %a1269      call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !111270      ret i16 11271    }1272    declare void @llvm.dbg.value(metadata, metadata, metadata)1273 1274    !llvm.dbg.cu = !{!0}1275    !llvm.module.flags = !{!5}1276 1277    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)1278    !1 = !DIFile(filename: "t.ll", directory: "/")1279    !2 = !{}1280    !5 = !{i32 2, !"Debug Info Version", i32 3}1281    !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)1282    !7 = !DISubroutineType(types: !2)1283    !8 = !{!9}1284    !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)1285    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)1286    !11 = !DILocation(line: 1, column: 1, scope: !6)1287)");1288 1289  BasicBlock &Entry = M->getFunction("f")->getEntryBlock();1290 1291  // Fetch the relevant instructions from the converted function.1292  Instruction *SubInst = &*Entry.begin();1293  ASSERT_TRUE(isa<BinaryOperator>(SubInst));1294  Instruction *AddInst = SubInst->getNextNode();1295  ASSERT_TRUE(isa<BinaryOperator>(AddInst));1296  Instruction *RetInst = AddInst->getNextNode();1297  ASSERT_TRUE(isa<ReturnInst>(RetInst));1298 1299  // add and sub should both have one DbgVariableRecord on add and ret.1300  EXPECT_FALSE(SubInst->hasDbgRecords());1301  EXPECT_TRUE(AddInst->hasDbgRecords());1302  EXPECT_TRUE(RetInst->hasDbgRecords());1303  auto R1 = AddInst->getDbgRecordRange();1304  EXPECT_EQ(std::distance(R1.begin(), R1.end()), 1u);1305  auto R2 = RetInst->getDbgRecordRange();1306  EXPECT_EQ(std::distance(R2.begin(), R2.end()), 1u);1307 1308  // The Supported (TM) code sequence for removing then reinserting insts1309  // after another instruction:1310  std::optional<DbgVariableRecord::self_iterator> Pos =1311      AddInst->getDbgReinsertionPosition();1312  AddInst->removeFromParent();1313 1314  // We should have a re-insertion position.1315  ASSERT_TRUE(Pos);1316  // Both DbgVariableRecords should now be attached to the ret inst.1317  auto R3 = RetInst->getDbgRecordRange();1318  EXPECT_EQ(std::distance(R3.begin(), R3.end()), 2u);1319 1320  // Re-insert and re-insert.1321  AddInst->insertAfter(SubInst->getIterator());1322  Entry.reinsertInstInDbgRecords(AddInst, Pos);1323  // We should be back into a position of having one DbgVariableRecord on add1324  // and ret.1325  EXPECT_FALSE(SubInst->hasDbgRecords());1326  EXPECT_TRUE(AddInst->hasDbgRecords());1327  EXPECT_TRUE(RetInst->hasDbgRecords());1328  auto R4 = AddInst->getDbgRecordRange();1329  EXPECT_EQ(std::distance(R4.begin(), R4.end()), 1u);1330  auto R5 = RetInst->getDbgRecordRange();1331  EXPECT_EQ(std::distance(R5.begin(), R5.end()), 1u);1332}1333 1334// Test instruction removal and re-insertion, this time with one1335// DbgVariableRecord that should hop up one instruction.1336TEST(BasicBlockDbgInfoTest, RemoveInstAndReinsertForOneDbgVariableRecord) {1337  LLVMContext C;1338  std::unique_ptr<Module> M = parseIR(C, R"(1339    define i16 @f(i16 %a) !dbg !6 {1340    entry:1341      %qux = sub i16 %a, 01342      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !111343      %foo = add i16 %a, %a1344      ret i16 11345    }1346    declare void @llvm.dbg.value(metadata, metadata, metadata)1347 1348    !llvm.dbg.cu = !{!0}1349    !llvm.module.flags = !{!5}1350 1351    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)1352    !1 = !DIFile(filename: "t.ll", directory: "/")1353    !2 = !{}1354    !5 = !{i32 2, !"Debug Info Version", i32 3}1355    !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)1356    !7 = !DISubroutineType(types: !2)1357    !8 = !{!9}1358    !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)1359    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)1360    !11 = !DILocation(line: 1, column: 1, scope: !6)1361)");1362 1363  BasicBlock &Entry = M->getFunction("f")->getEntryBlock();1364 1365  // Fetch the relevant instructions from the converted function.1366  Instruction *SubInst = &*Entry.begin();1367  ASSERT_TRUE(isa<BinaryOperator>(SubInst));1368  Instruction *AddInst = SubInst->getNextNode();1369  ASSERT_TRUE(isa<BinaryOperator>(AddInst));1370  Instruction *RetInst = AddInst->getNextNode();1371  ASSERT_TRUE(isa<ReturnInst>(RetInst));1372 1373  // There should be one DbgVariableRecord.1374  EXPECT_FALSE(SubInst->hasDbgRecords());1375  EXPECT_TRUE(AddInst->hasDbgRecords());1376  EXPECT_FALSE(RetInst->hasDbgRecords());1377  auto R1 = AddInst->getDbgRecordRange();1378  EXPECT_EQ(std::distance(R1.begin(), R1.end()), 1u);1379 1380  // The Supported (TM) code sequence for removing then reinserting insts:1381  std::optional<DbgVariableRecord::self_iterator> Pos =1382      AddInst->getDbgReinsertionPosition();1383  AddInst->removeFromParent();1384 1385  // No re-insertion position as there were no DbgVariableRecords on the ret.1386  ASSERT_FALSE(Pos);1387  // The single DbgVariableRecord should now be attached to the ret inst.1388  EXPECT_TRUE(RetInst->hasDbgRecords());1389  auto R2 = RetInst->getDbgRecordRange();1390  EXPECT_EQ(std::distance(R2.begin(), R2.end()), 1u);1391 1392  // Re-insert and re-insert.1393  AddInst->insertAfter(SubInst->getIterator());1394  Entry.reinsertInstInDbgRecords(AddInst, Pos);1395  // We should be back into a position of having one DbgVariableRecord on the1396  // AddInst.1397  EXPECT_FALSE(SubInst->hasDbgRecords());1398  EXPECT_TRUE(AddInst->hasDbgRecords());1399  EXPECT_FALSE(RetInst->hasDbgRecords());1400  auto R3 = AddInst->getDbgRecordRange();1401  EXPECT_EQ(std::distance(R3.begin(), R3.end()), 1u);1402}1403 1404// Similar to the above, what if we splice into an empty block with debug-info,1405// with debug-info at the start of the moving range, that we intend to be1406// transferred. The dbg.value of %a should remain at the start, but come ahead1407// of the i16 0 dbg.value.1408TEST(BasicBlockDbgInfoTest, DbgSpliceToEmpty1) {1409  LLVMContext C;1410  std::unique_ptr<Module> M = parseIR(C, R"(1411    define i16 @f(i16 %a) !dbg !6 {1412    entry:1413      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !111414      br label %exit1415 1416    exit:1417      call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !111418      %b = add i16 %a, 1, !dbg !111419      call void @llvm.dbg.value(metadata i16 1, metadata !9, metadata !DIExpression()), !dbg !111420      ret i16 0, !dbg !111421    }1422    declare void @llvm.dbg.value(metadata, metadata, metadata) #01423    attributes #0 = { nounwind readnone speculatable willreturn }1424 1425    !llvm.dbg.cu = !{!0}1426    !llvm.module.flags = !{!5}1427 1428    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)1429    !1 = !DIFile(filename: "t.ll", directory: "/")1430    !2 = !{}1431    !5 = !{i32 2, !"Debug Info Version", i32 3}1432    !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)1433    !7 = !DISubroutineType(types: !2)1434    !8 = !{!9}1435    !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)1436    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)1437    !11 = !DILocation(line: 1, column: 1, scope: !6)1438)");1439 1440  Function &F = *M->getFunction("f");1441  BasicBlock &Entry = F.getEntryBlock();1442  BasicBlock &Exit = *Entry.getNextNode();1443 1444  // Begin by forcing entry block to have dangling DbgVariableRecord.1445  Entry.getTerminator()->eraseFromParent();1446  ASSERT_NE(Entry.getTrailingDbgRecords(), nullptr);1447  EXPECT_TRUE(Entry.empty());1448 1449  // Now transfer the entire contents of the exit block into the entry. This1450  // includes both dbg.values.1451  Entry.splice(Entry.end(), &Exit, Exit.begin(), Exit.end());1452 1453  // We should now have two dbg.values on the first instruction, and they1454  // should be in the correct order of %a, then 0.1455  Instruction *BInst = &*Entry.begin();1456  ASSERT_TRUE(BInst->hasDbgRecords());1457  EXPECT_EQ(BInst->DebugMarker->StoredDbgRecords.size(), 2u);1458  SmallVector<DbgVariableRecord *, 2> DbgVariableRecords;1459  for (DbgRecord &DVR : BInst->getDbgRecordRange())1460    DbgVariableRecords.push_back(cast<DbgVariableRecord>(&DVR));1461 1462  EXPECT_EQ(DbgVariableRecords[0]->getVariableLocationOp(0), F.getArg(0));1463  Value *SecondDVRValue = DbgVariableRecords[1]->getVariableLocationOp(0);1464  ASSERT_TRUE(isa<ConstantInt>(SecondDVRValue));1465  EXPECT_EQ(cast<ConstantInt>(SecondDVRValue)->getZExtValue(), 0ull);1466 1467  // No trailing DbgVariableRecords in the entry block now.1468  EXPECT_EQ(Entry.getTrailingDbgRecords(), nullptr);1469}1470 1471// Similar test again, but this time: splice the contents of exit into entry,1472// with the intention of leaving the first dbg.value (i16 0) behind.1473TEST(BasicBlockDbgInfoTest, DbgSpliceToEmpty2) {1474  LLVMContext C;1475  std::unique_ptr<Module> M = parseIR(C, R"(1476    define i16 @f(i16 %a) !dbg !6 {1477    entry:1478      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !111479      br label %exit1480 1481    exit:1482      call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !111483      %b = add i16 %a, 1, !dbg !111484      call void @llvm.dbg.value(metadata i16 1, metadata !9, metadata !DIExpression()), !dbg !111485      ret i16 0, !dbg !111486    }1487    declare void @llvm.dbg.value(metadata, metadata, metadata) #01488    attributes #0 = { nounwind readnone speculatable willreturn }1489 1490    !llvm.dbg.cu = !{!0}1491    !llvm.module.flags = !{!5}1492 1493    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)1494    !1 = !DIFile(filename: "t.ll", directory: "/")1495    !2 = !{}1496    !5 = !{i32 2, !"Debug Info Version", i32 3}1497    !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)1498    !7 = !DISubroutineType(types: !2)1499    !8 = !{!9}1500    !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)1501    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)1502    !11 = !DILocation(line: 1, column: 1, scope: !6)1503)");1504 1505  Function &F = *M->getFunction("f");1506  BasicBlock &Entry = F.getEntryBlock();1507  BasicBlock &Exit = *Entry.getNextNode();1508 1509  // Begin by forcing entry block to have dangling DbgVariableRecord.1510  Entry.getTerminator()->eraseFromParent();1511  ASSERT_NE(Entry.getTrailingDbgRecords(), nullptr);1512  EXPECT_TRUE(Entry.empty());1513 1514  // Now transfer into the entry block -- fetching the first instruction with1515  // begin and then calling getIterator clears the "head" bit, meaning that the1516  // range to move will not include any leading DbgVariableRecords.1517  Entry.splice(Entry.end(), &Exit, Exit.begin()->getIterator(), Exit.end());1518 1519  // We should now have one dbg.values on the first instruction, %a.1520  Instruction *BInst = &*Entry.begin();1521  ASSERT_TRUE(BInst->hasDbgRecords());1522  EXPECT_EQ(BInst->DebugMarker->StoredDbgRecords.size(), 1u);1523  SmallVector<DbgVariableRecord *, 2> DbgVariableRecords;1524  for (DbgRecord &DVR : BInst->getDbgRecordRange())1525    DbgVariableRecords.push_back(cast<DbgVariableRecord>(&DVR));1526 1527  EXPECT_EQ(DbgVariableRecords[0]->getVariableLocationOp(0), F.getArg(0));1528  // No trailing DbgVariableRecords in the entry block now.1529  EXPECT_EQ(Entry.getTrailingDbgRecords(), nullptr);1530 1531  // We should have nothing left in the exit block...1532  EXPECT_TRUE(Exit.empty());1533  // ... except for some dangling DbgVariableRecords.1534  EXPECT_NE(Exit.getTrailingDbgRecords(), nullptr);1535  EXPECT_FALSE(Exit.getTrailingDbgRecords()->empty());1536  Exit.getTrailingDbgRecords()->eraseFromParent();1537  Exit.deleteTrailingDbgRecords();1538}1539 1540// What if we moveBefore end() -- there might be no debug-info there, in which1541// case we shouldn't crash.1542TEST(BasicBlockDbgInfoTest, DbgMoveToEnd) {1543  LLVMContext C;1544  std::unique_ptr<Module> M = parseIR(C, R"(1545    define i16 @f(i16 %a) !dbg !6 {1546    entry:1547      br label %exit1548 1549    exit:1550      ret i16 0, !dbg !111551    }1552    declare void @llvm.dbg.value(metadata, metadata, metadata) #01553    attributes #0 = { nounwind readnone speculatable willreturn }1554 1555    !llvm.dbg.cu = !{!0}1556    !llvm.module.flags = !{!5}1557 1558    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)1559    !1 = !DIFile(filename: "t.ll", directory: "/")1560    !2 = !{}1561    !5 = !{i32 2, !"Debug Info Version", i32 3}1562    !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)1563    !7 = !DISubroutineType(types: !2)1564    !8 = !{!9}1565    !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)1566    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)1567    !11 = !DILocation(line: 1, column: 1, scope: !6)1568)");1569 1570  Function &F = *M->getFunction("f");1571  BasicBlock &Entry = F.getEntryBlock();1572  BasicBlock &Exit = *Entry.getNextNode();1573 1574  // Move the return to the end of the entry block.1575  Instruction *Br = Entry.getTerminator();1576  Instruction *Ret = Exit.getTerminator();1577  EXPECT_EQ(Entry.getTrailingDbgRecords(), nullptr);1578  Ret->moveBefore(Entry, Entry.end());1579  Br->eraseFromParent();1580 1581  // There should continue to not be any debug-info anywhere.1582  EXPECT_EQ(Entry.getTrailingDbgRecords(), nullptr);1583  EXPECT_EQ(Exit.getTrailingDbgRecords(), nullptr);1584  EXPECT_FALSE(Ret->hasDbgRecords());1585}1586 1587TEST(BasicBlockDbgInfoTest, CloneTrailingRecordsToEmptyBlock) {1588  LLVMContext C;1589  std::unique_ptr<Module> M = parseIR(C, R"(1590    define i16 @foo(i16 %a) !dbg !6 {1591    entry:1592      %b = add i16 %a, 01593        #dbg_value(i16 %b, !9, !DIExpression(), !11)1594      ret i16 0, !dbg !111595    }1596 1597    !llvm.dbg.cu = !{!0}1598    !llvm.module.flags = !{!5}1599 1600    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)1601    !1 = !DIFile(filename: "t.ll", directory: "/")1602    !2 = !{}1603    !5 = !{i32 2, !"Debug Info Version", i32 3}1604    !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)1605    !7 = !DISubroutineType(types: !2)1606    !8 = !{!9}1607    !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)1608    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)1609    !11 = !DILocation(line: 1, column: 1, scope: !6)1610)");1611  ASSERT_TRUE(M);1612 1613  Function *F = M->getFunction("foo");1614  BasicBlock &BB = F->getEntryBlock();1615  // Start with no trailing records.1616  ASSERT_FALSE(BB.getTrailingDbgRecords());1617 1618  BasicBlock::iterator Ret = std::prev(BB.end());1619  BasicBlock::iterator B = std::prev(Ret);1620 1621  // Delete terminator which has debug records: we now get trailing records.1622  Ret->eraseFromParent();1623  EXPECT_TRUE(BB.getTrailingDbgRecords());1624 1625  BasicBlock *NewBB = BasicBlock::Create(C, "NewBB", F);1626  NewBB->splice(NewBB->end(), &BB, B, BB.end());1627 1628  // The trailing records should've been absorbed into NewBB.1629  EXPECT_FALSE(BB.getTrailingDbgRecords());1630  EXPECT_TRUE(NewBB->getTrailingDbgRecords());1631  if (DbgMarker *Trailing = NewBB->getTrailingDbgRecords()) {1632    EXPECT_EQ(llvm::range_size(Trailing->getDbgRecordRange()), 1u);1633    // Drop the trailing records now, to prevent a cleanup assertion.1634    Trailing->eraseFromParent();1635    NewBB->deleteTrailingDbgRecords();1636  }1637}1638 1639} // End anonymous namespace.1640