llvm-project

Форк
0
/
BasicBlockDbgInfoTest.cpp 
1528 строк · 59.9 Кб
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);
145
  BB.splitBasicBlockBefore(I, "before");
146

147
  BasicBlock &BBBefore = F->getEntryBlock();
148
  auto I2 = std::prev(BBBefore.end(), 2);
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);
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);
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);
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
} // End anonymous namespace.
1529

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.