• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- Local.cpp - Unit tests for Local -----------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/Transforms/Utils/Local.h"
11 #include "llvm/AsmParser/Parser.h"
12 #include "llvm/IR/BasicBlock.h"
13 #include "llvm/IR/DIBuilder.h"
14 #include "llvm/IR/IRBuilder.h"
15 #include "llvm/IR/Instructions.h"
16 #include "llvm/IR/IntrinsicInst.h"
17 #include "llvm/IR/LLVMContext.h"
18 #include "llvm/IR/Verifier.h"
19 #include "llvm/Support/SourceMgr.h"
20 #include "gtest/gtest.h"
21 
22 using namespace llvm;
23 
TEST(Local,RecursivelyDeleteDeadPHINodes)24 TEST(Local, RecursivelyDeleteDeadPHINodes) {
25   LLVMContext C;
26 
27   IRBuilder<> builder(C);
28 
29   // Make blocks
30   BasicBlock *bb0 = BasicBlock::Create(C);
31   BasicBlock *bb1 = BasicBlock::Create(C);
32 
33   builder.SetInsertPoint(bb0);
34   PHINode    *phi = builder.CreatePHI(Type::getInt32Ty(C), 2);
35   BranchInst *br0 = builder.CreateCondBr(builder.getTrue(), bb0, bb1);
36 
37   builder.SetInsertPoint(bb1);
38   BranchInst *br1 = builder.CreateBr(bb0);
39 
40   phi->addIncoming(phi, bb0);
41   phi->addIncoming(phi, bb1);
42 
43   // The PHI will be removed
44   EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));
45 
46   // Make sure the blocks only contain the branches
47   EXPECT_EQ(&bb0->front(), br0);
48   EXPECT_EQ(&bb1->front(), br1);
49 
50   builder.SetInsertPoint(bb0);
51   phi = builder.CreatePHI(Type::getInt32Ty(C), 0);
52 
53   EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));
54 
55   builder.SetInsertPoint(bb0);
56   phi = builder.CreatePHI(Type::getInt32Ty(C), 0);
57   builder.CreateAdd(phi, phi);
58 
59   EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));
60 
61   bb0->dropAllReferences();
62   bb1->dropAllReferences();
63   delete bb0;
64   delete bb1;
65 }
66 
TEST(Local,RemoveDuplicatePHINodes)67 TEST(Local, RemoveDuplicatePHINodes) {
68   LLVMContext C;
69   IRBuilder<> B(C);
70 
71   std::unique_ptr<Function> F(
72       Function::Create(FunctionType::get(B.getVoidTy(), false),
73                        GlobalValue::ExternalLinkage, "F"));
74   BasicBlock *Entry(BasicBlock::Create(C, "", F.get()));
75   BasicBlock *BB(BasicBlock::Create(C, "", F.get()));
76   BranchInst::Create(BB, Entry);
77 
78   B.SetInsertPoint(BB);
79 
80   AssertingVH<PHINode> P1 = B.CreatePHI(Type::getInt32Ty(C), 2);
81   P1->addIncoming(B.getInt32(42), Entry);
82 
83   PHINode *P2 = B.CreatePHI(Type::getInt32Ty(C), 2);
84   P2->addIncoming(B.getInt32(42), Entry);
85 
86   AssertingVH<PHINode> P3 = B.CreatePHI(Type::getInt32Ty(C), 2);
87   P3->addIncoming(B.getInt32(42), Entry);
88   P3->addIncoming(B.getInt32(23), BB);
89 
90   PHINode *P4 = B.CreatePHI(Type::getInt32Ty(C), 2);
91   P4->addIncoming(B.getInt32(42), Entry);
92   P4->addIncoming(B.getInt32(23), BB);
93 
94   P1->addIncoming(P3, BB);
95   P2->addIncoming(P4, BB);
96   BranchInst::Create(BB, BB);
97 
98   // Verify that we can eliminate PHIs that become duplicates after chaning PHIs
99   // downstream.
100   EXPECT_TRUE(EliminateDuplicatePHINodes(BB));
101   EXPECT_EQ(3U, BB->size());
102 }
103 
parseIR(LLVMContext & C,const char * IR)104 static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
105   SMDiagnostic Err;
106   std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
107   if (!Mod)
108     Err.print("UtilsTests", errs());
109   return Mod;
110 }
111 
TEST(Local,ReplaceDbgDeclare)112 TEST(Local, ReplaceDbgDeclare) {
113   LLVMContext C;
114 
115   // Original C source to get debug info for a local variable:
116   // void f() { int x; }
117   std::unique_ptr<Module> M = parseIR(C,
118                                       R"(
119       define void @f() !dbg !8 {
120       entry:
121         %x = alloca i32, align 4
122         call void @llvm.dbg.declare(metadata i32* %x, metadata !11, metadata !DIExpression()), !dbg !13
123         call void @llvm.dbg.declare(metadata i32* %x, metadata !11, metadata !DIExpression()), !dbg !13
124         ret void, !dbg !14
125       }
126       declare void @llvm.dbg.declare(metadata, metadata, metadata)
127       !llvm.dbg.cu = !{!0}
128       !llvm.module.flags = !{!3, !4}
129       !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
130       !1 = !DIFile(filename: "t2.c", directory: "foo")
131       !2 = !{}
132       !3 = !{i32 2, !"Dwarf Version", i32 4}
133       !4 = !{i32 2, !"Debug Info Version", i32 3}
134       !8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, retainedNodes: !2)
135       !9 = !DISubroutineType(types: !10)
136       !10 = !{null}
137       !11 = !DILocalVariable(name: "x", scope: !8, file: !1, line: 2, type: !12)
138       !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
139       !13 = !DILocation(line: 2, column: 7, scope: !8)
140       !14 = !DILocation(line: 3, column: 1, scope: !8)
141       )");
142   auto *GV = M->getNamedValue("f");
143   ASSERT_TRUE(GV);
144   auto *F = dyn_cast<Function>(GV);
145   ASSERT_TRUE(F);
146   Instruction *Inst = &F->front().front();
147   auto *AI = dyn_cast<AllocaInst>(Inst);
148   ASSERT_TRUE(AI);
149   Inst = Inst->getNextNode()->getNextNode();
150   ASSERT_TRUE(Inst);
151   auto *DII = dyn_cast<DbgDeclareInst>(Inst);
152   ASSERT_TRUE(DII);
153   Value *NewBase = Constant::getNullValue(Type::getInt32PtrTy(C));
154   DIBuilder DIB(*M);
155   replaceDbgDeclare(AI, NewBase, DII, DIB, DIExpression::NoDeref, 0,
156                     DIExpression::NoDeref);
157 
158   // There should be exactly two dbg.declares.
159   int Declares = 0;
160   for (const Instruction &I : F->front())
161     if (isa<DbgDeclareInst>(I))
162       Declares++;
163   EXPECT_EQ(2, Declares);
164 }
165 
166 /// Build the dominator tree for the function and run the Test.
runWithDomTree(Module & M,StringRef FuncName,function_ref<void (Function & F,DominatorTree * DT)> Test)167 static void runWithDomTree(
168     Module &M, StringRef FuncName,
169     function_ref<void(Function &F, DominatorTree *DT)> Test) {
170   auto *F = M.getFunction(FuncName);
171   ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
172   // Compute the dominator tree for the function.
173   DominatorTree DT(*F);
174   Test(*F, &DT);
175 }
176 
TEST(Local,MergeBasicBlockIntoOnlyPred)177 TEST(Local, MergeBasicBlockIntoOnlyPred) {
178   LLVMContext C;
179 
180   std::unique_ptr<Module> M = parseIR(C,
181                                       R"(
182       define i32 @f(i8* %str) {
183       entry:
184         br label %bb2.i
185       bb2.i:                                            ; preds = %bb4.i, %entry
186         br i1 false, label %bb4.i, label %base2flt.exit204
187       bb4.i:                                            ; preds = %bb2.i
188         br i1 false, label %base2flt.exit204, label %bb2.i
189       bb10.i196.bb7.i197_crit_edge:                     ; No predecessors!
190         br label %bb7.i197
191       bb7.i197:                                         ; preds = %bb10.i196.bb7.i197_crit_edge
192         %.reg2mem.0 = phi i32 [ %.reg2mem.0, %bb10.i196.bb7.i197_crit_edge ]
193         br i1 undef, label %base2flt.exit204, label %base2flt.exit204
194       base2flt.exit204:                                 ; preds = %bb7.i197, %bb7.i197, %bb2.i, %bb4.i
195         ret i32 0
196       }
197       )");
198   runWithDomTree(
199       *M, "f", [&](Function &F, DominatorTree *DT) {
200         for (Function::iterator I = F.begin(), E = F.end(); I != E;) {
201           BasicBlock *BB = &*I++;
202           BasicBlock *SinglePred = BB->getSinglePredecessor();
203           if (!SinglePred || SinglePred == BB || BB->hasAddressTaken()) continue;
204           BranchInst *Term = dyn_cast<BranchInst>(SinglePred->getTerminator());
205           if (Term && !Term->isConditional())
206             MergeBasicBlockIntoOnlyPred(BB, DT);
207         }
208         EXPECT_TRUE(DT->verify());
209       });
210 }
211 
TEST(Local,ConstantFoldTerminator)212 TEST(Local, ConstantFoldTerminator) {
213   LLVMContext C;
214 
215   std::unique_ptr<Module> M = parseIR(C,
216                                       R"(
217       define void @br_same_dest() {
218       entry:
219         br i1 false, label %bb0, label %bb0
220       bb0:
221         ret void
222       }
223 
224       define void @br_different_dest() {
225       entry:
226         br i1 true, label %bb0, label %bb1
227       bb0:
228         br label %exit
229       bb1:
230         br label %exit
231       exit:
232         ret void
233       }
234 
235       define void @switch_2_different_dest() {
236       entry:
237         switch i32 0, label %default [ i32 0, label %bb0 ]
238       default:
239         ret void
240       bb0:
241         ret void
242       }
243       define void @switch_2_different_dest_default() {
244       entry:
245         switch i32 1, label %default [ i32 0, label %bb0 ]
246       default:
247         ret void
248       bb0:
249         ret void
250       }
251       define void @switch_3_different_dest() {
252       entry:
253         switch i32 0, label %default [ i32 0, label %bb0
254                                        i32 1, label %bb1 ]
255       default:
256         ret void
257       bb0:
258         ret void
259       bb1:
260         ret void
261       }
262 
263       define void @switch_variable_2_default_dest(i32 %arg) {
264       entry:
265         switch i32 %arg, label %default [ i32 0, label %default ]
266       default:
267         ret void
268       }
269 
270       define void @switch_constant_2_default_dest() {
271       entry:
272         switch i32 1, label %default [ i32 0, label %default ]
273       default:
274         ret void
275       }
276 
277       define void @switch_constant_3_repeated_dest() {
278       entry:
279         switch i32 0, label %default [ i32 0, label %bb0
280                                        i32 1, label %bb0 ]
281        bb0:
282          ret void
283       default:
284         ret void
285       }
286 
287       define void @indirectbr() {
288       entry:
289         indirectbr i8* blockaddress(@indirectbr, %bb0), [label %bb0, label %bb1]
290       bb0:
291         ret void
292       bb1:
293         ret void
294       }
295 
296       define void @indirectbr_repeated() {
297       entry:
298         indirectbr i8* blockaddress(@indirectbr_repeated, %bb0), [label %bb0, label %bb0]
299       bb0:
300         ret void
301       }
302 
303       define void @indirectbr_unreachable() {
304       entry:
305         indirectbr i8* blockaddress(@indirectbr_unreachable, %bb0), [label %bb1]
306       bb0:
307         ret void
308       bb1:
309         ret void
310       }
311         )");
312 
313   auto CFAllTerminators = [&](Function &F, DominatorTree *DT) {
314     DeferredDominance DDT(*DT);
315     for (Function::iterator I = F.begin(), E = F.end(); I != E;) {
316       BasicBlock *BB = &*I++;
317       ConstantFoldTerminator(BB, true, nullptr, &DDT);
318     }
319 
320     EXPECT_TRUE(DDT.flush().verify());
321   };
322 
323   runWithDomTree(*M, "br_same_dest", CFAllTerminators);
324   runWithDomTree(*M, "br_different_dest", CFAllTerminators);
325   runWithDomTree(*M, "switch_2_different_dest", CFAllTerminators);
326   runWithDomTree(*M, "switch_2_different_dest_default", CFAllTerminators);
327   runWithDomTree(*M, "switch_3_different_dest", CFAllTerminators);
328   runWithDomTree(*M, "switch_variable_2_default_dest", CFAllTerminators);
329   runWithDomTree(*M, "switch_constant_2_default_dest", CFAllTerminators);
330   runWithDomTree(*M, "switch_constant_3_repeated_dest", CFAllTerminators);
331   runWithDomTree(*M, "indirectbr", CFAllTerminators);
332   runWithDomTree(*M, "indirectbr_repeated", CFAllTerminators);
333   runWithDomTree(*M, "indirectbr_unreachable", CFAllTerminators);
334 }
335 
336 struct SalvageDebugInfoTest : ::testing::Test {
337   LLVMContext C;
338   std::unique_ptr<Module> M;
339   Function *F = nullptr;
340 
SetUpSalvageDebugInfoTest341   void SetUp() {
342     M = parseIR(C,
343                 R"(
344       define void @f() !dbg !8 {
345       entry:
346         %x = add i32 0, 1
347         %y = add i32 %x, 2
348         call void @llvm.dbg.value(metadata i32 %x, metadata !11, metadata !DIExpression()), !dbg !13
349         call void @llvm.dbg.value(metadata i32 %y, metadata !11, metadata !DIExpression()), !dbg !13
350         ret void, !dbg !14
351       }
352       declare void @llvm.dbg.value(metadata, metadata, metadata)
353       !llvm.dbg.cu = !{!0}
354       !llvm.module.flags = !{!3, !4}
355       !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
356       !1 = !DIFile(filename: "t2.c", directory: "foo")
357       !2 = !{}
358       !3 = !{i32 2, !"Dwarf Version", i32 4}
359       !4 = !{i32 2, !"Debug Info Version", i32 3}
360       !8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, retainedNodes: !2)
361       !9 = !DISubroutineType(types: !10)
362       !10 = !{null}
363       !11 = !DILocalVariable(name: "x", scope: !8, file: !1, line: 2, type: !12)
364       !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
365       !13 = !DILocation(line: 2, column: 7, scope: !8)
366       !14 = !DILocation(line: 3, column: 1, scope: !8)
367       )");
368 
369     auto *GV = M->getNamedValue("f");
370     ASSERT_TRUE(GV);
371     F = dyn_cast<Function>(GV);
372     ASSERT_TRUE(F);
373   }
374 
doesDebugValueDescribeXSalvageDebugInfoTest375   bool doesDebugValueDescribeX(const DbgValueInst &DI) {
376     const auto &CI = *cast<ConstantInt>(DI.getValue());
377     if (CI.isZero())
378       return DI.getExpression()->getElements().equals(
379           {dwarf::DW_OP_plus_uconst, 1, dwarf::DW_OP_stack_value});
380     else if (CI.isOneValue())
381       return DI.getExpression()->getElements().empty();
382     return false;
383   }
384 
doesDebugValueDescribeYSalvageDebugInfoTest385   bool doesDebugValueDescribeY(const DbgValueInst &DI) {
386     const auto &CI = *cast<ConstantInt>(DI.getValue());
387     if (CI.isZero())
388       return DI.getExpression()->getElements().equals(
389           {dwarf::DW_OP_plus_uconst, 1, dwarf::DW_OP_plus_uconst, 2,
390            dwarf::DW_OP_stack_value});
391     else if (CI.isOneValue())
392       return DI.getExpression()->getElements().equals(
393           {dwarf::DW_OP_plus_uconst, 2, dwarf::DW_OP_stack_value});
394     return false;
395   }
396 
verifyDebugValuesAreSalvagedSalvageDebugInfoTest397   void verifyDebugValuesAreSalvaged() {
398     // Check that the debug values for %x and %y are preserved.
399     bool FoundX = false;
400     bool FoundY = false;
401     for (const Instruction &I : F->front()) {
402       auto DI = dyn_cast<DbgValueInst>(&I);
403       if (!DI) {
404         // The function should only contain debug values and a terminator.
405         ASSERT_TRUE(isa<TerminatorInst>(&I));
406         continue;
407       }
408       EXPECT_EQ(DI->getVariable()->getName(), "x");
409       FoundX |= doesDebugValueDescribeX(*DI);
410       FoundY |= doesDebugValueDescribeY(*DI);
411     }
412     ASSERT_TRUE(FoundX);
413     ASSERT_TRUE(FoundY);
414   }
415 };
416 
TEST_F(SalvageDebugInfoTest,RecursiveInstDeletion)417 TEST_F(SalvageDebugInfoTest, RecursiveInstDeletion) {
418   Instruction *Inst = &F->front().front();
419   Inst = Inst->getNextNode(); // Get %y = add ...
420   ASSERT_TRUE(Inst);
421   bool Deleted = RecursivelyDeleteTriviallyDeadInstructions(Inst);
422   ASSERT_TRUE(Deleted);
423   verifyDebugValuesAreSalvaged();
424 }
425 
TEST_F(SalvageDebugInfoTest,RecursiveBlockSimplification)426 TEST_F(SalvageDebugInfoTest, RecursiveBlockSimplification) {
427   BasicBlock *BB = &F->front();
428   ASSERT_TRUE(BB);
429   bool Deleted = SimplifyInstructionsInBlock(BB);
430   ASSERT_TRUE(Deleted);
431   verifyDebugValuesAreSalvaged();
432 }
433 
TEST(Local,ReplaceAllDbgUsesWith)434 TEST(Local, ReplaceAllDbgUsesWith) {
435   using namespace llvm::dwarf;
436 
437   LLVMContext Ctx;
438 
439   // Note: The datalayout simulates Darwin/x86_64.
440   std::unique_ptr<Module> M = parseIR(Ctx,
441                                       R"(
442     target datalayout = "e-m:o-i63:64-f80:128-n8:16:32:64-S128"
443 
444     declare i32 @escape(i32)
445 
446     define void @f() !dbg !6 {
447     entry:
448       %a = add i32 0, 1, !dbg !15
449       call void @llvm.dbg.value(metadata i32 %a, metadata !9, metadata !DIExpression()), !dbg !15
450 
451       %b = add i64 0, 1, !dbg !16
452       call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression()), !dbg !16
453       call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression(DW_OP_lit0, DW_OP_mul)), !dbg !16
454       call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression(DW_OP_lit0, DW_OP_mul, DW_OP_stack_value)), !dbg !16
455       call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 8)), !dbg !16
456       call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression(DW_OP_lit0, DW_OP_mul, DW_OP_LLVM_fragment, 0, 8)), !dbg !16
457       call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression(DW_OP_lit0, DW_OP_mul, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8)), !dbg !16
458 
459       %c = inttoptr i64 0 to i64*, !dbg !17
460       call void @llvm.dbg.declare(metadata i64* %c, metadata !13, metadata !DIExpression()), !dbg !17
461 
462       %d = inttoptr i64 0 to i32*, !dbg !18
463       call void @llvm.dbg.addr(metadata i32* %d, metadata !20, metadata !DIExpression()), !dbg !18
464 
465       %e = add <2 x i16> zeroinitializer, zeroinitializer
466       call void @llvm.dbg.value(metadata <2 x i16> %e, metadata !14, metadata !DIExpression()), !dbg !18
467 
468       %f = call i32 @escape(i32 0)
469       call void @llvm.dbg.value(metadata i32 %f, metadata !9, metadata !DIExpression()), !dbg !15
470 
471       %barrier = call i32 @escape(i32 0)
472 
473       %g = call i32 @escape(i32 %f)
474       call void @llvm.dbg.value(metadata i32 %g, metadata !9, metadata !DIExpression()), !dbg !15
475 
476       ret void, !dbg !19
477     }
478 
479     declare void @llvm.dbg.addr(metadata, metadata, metadata)
480     declare void @llvm.dbg.declare(metadata, metadata, metadata)
481     declare void @llvm.dbg.value(metadata, metadata, metadata)
482 
483     !llvm.dbg.cu = !{!0}
484     !llvm.module.flags = !{!5}
485 
486     !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
487     !1 = !DIFile(filename: "/Users/vsk/Desktop/foo.ll", directory: "/")
488     !2 = !{}
489     !5 = !{i32 2, !"Debug Info Version", i32 3}
490     !6 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !0, retainedNodes: !8)
491     !7 = !DISubroutineType(types: !2)
492     !8 = !{!9, !11, !13, !14}
493     !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
494     !10 = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_signed)
495     !11 = !DILocalVariable(name: "2", scope: !6, file: !1, line: 2, type: !12)
496     !12 = !DIBasicType(name: "ty64", size: 64, encoding: DW_ATE_signed)
497     !13 = !DILocalVariable(name: "3", scope: !6, file: !1, line: 3, type: !12)
498     !14 = !DILocalVariable(name: "4", scope: !6, file: !1, line: 4, type: !10)
499     !15 = !DILocation(line: 1, column: 1, scope: !6)
500     !16 = !DILocation(line: 2, column: 1, scope: !6)
501     !17 = !DILocation(line: 3, column: 1, scope: !6)
502     !18 = !DILocation(line: 4, column: 1, scope: !6)
503     !19 = !DILocation(line: 5, column: 1, scope: !6)
504     !20 = !DILocalVariable(name: "5", scope: !6, file: !1, line: 5, type: !10)
505   )");
506 
507   bool BrokenDebugInfo = true;
508   verifyModule(*M, &errs(), &BrokenDebugInfo);
509   ASSERT_FALSE(BrokenDebugInfo);
510 
511   Function &F = *cast<Function>(M->getNamedValue("f"));
512   DominatorTree DT{F};
513 
514   BasicBlock &BB = F.front();
515   Instruction &A = BB.front();
516   Instruction &B = *A.getNextNonDebugInstruction();
517   Instruction &C = *B.getNextNonDebugInstruction();
518   Instruction &D = *C.getNextNonDebugInstruction();
519   Instruction &E = *D.getNextNonDebugInstruction();
520   Instruction &F_ = *E.getNextNonDebugInstruction();
521   Instruction &Barrier = *F_.getNextNonDebugInstruction();
522   Instruction &G = *Barrier.getNextNonDebugInstruction();
523 
524   // Simulate i32 <-> i64* conversion. Expect no updates: the datalayout says
525   // pointers are 64 bits, so the conversion would be lossy.
526   EXPECT_FALSE(replaceAllDbgUsesWith(A, C, C, DT));
527   EXPECT_FALSE(replaceAllDbgUsesWith(C, A, A, DT));
528 
529   // Simulate i32 <-> <2 x i16> conversion. This is unsupported.
530   EXPECT_FALSE(replaceAllDbgUsesWith(E, A, A, DT));
531   EXPECT_FALSE(replaceAllDbgUsesWith(A, E, E, DT));
532 
533   // Simulate i32* <-> i64* conversion.
534   EXPECT_TRUE(replaceAllDbgUsesWith(D, C, C, DT));
535 
536   SmallVector<DbgInfoIntrinsic *, 2> CDbgVals;
537   findDbgUsers(CDbgVals, &C);
538   EXPECT_EQ(2U, CDbgVals.size());
539   EXPECT_TRUE(any_of(CDbgVals, [](DbgInfoIntrinsic *DII) {
540     return isa<DbgAddrIntrinsic>(DII);
541   }));
542   EXPECT_TRUE(any_of(CDbgVals, [](DbgInfoIntrinsic *DII) {
543     return isa<DbgDeclareInst>(DII);
544   }));
545 
546   EXPECT_TRUE(replaceAllDbgUsesWith(C, D, D, DT));
547 
548   SmallVector<DbgInfoIntrinsic *, 2> DDbgVals;
549   findDbgUsers(DDbgVals, &D);
550   EXPECT_EQ(2U, DDbgVals.size());
551   EXPECT_TRUE(any_of(DDbgVals, [](DbgInfoIntrinsic *DII) {
552     return isa<DbgAddrIntrinsic>(DII);
553   }));
554   EXPECT_TRUE(any_of(DDbgVals, [](DbgInfoIntrinsic *DII) {
555     return isa<DbgDeclareInst>(DII);
556   }));
557 
558   // Introduce a use-before-def. Check that the dbg.value for %a is salvaged.
559   EXPECT_TRUE(replaceAllDbgUsesWith(A, F_, F_, DT));
560 
561   auto *ADbgVal = cast<DbgValueInst>(A.getNextNode());
562   EXPECT_EQ(ConstantInt::get(A.getType(), 0), ADbgVal->getVariableLocation());
563 
564   // Introduce a use-before-def. Check that the dbg.values for %f are deleted.
565   EXPECT_TRUE(replaceAllDbgUsesWith(F_, G, G, DT));
566 
567   SmallVector<DbgValueInst *, 1> FDbgVals;
568   findDbgValues(FDbgVals, &F);
569   EXPECT_EQ(0U, FDbgVals.size());
570 
571   // Simulate i32 -> i64 conversion to test sign-extension. Here are some
572   // interesting cases to handle:
573   //  1) debug user has empty DIExpression
574   //  2) debug user has non-empty, non-stack-value'd DIExpression
575   //  3) debug user has non-empty, stack-value'd DIExpression
576   //  4-6) like (1-3), but with a fragment
577   EXPECT_TRUE(replaceAllDbgUsesWith(B, A, A, DT));
578 
579   SmallVector<DbgValueInst *, 8> ADbgVals;
580   findDbgValues(ADbgVals, &A);
581   EXPECT_EQ(6U, ADbgVals.size());
582 
583   // Check that %a has a dbg.value with a DIExpression matching \p Ops.
584   auto hasADbgVal = [&](ArrayRef<uint64_t> Ops) {
585     return any_of(ADbgVals, [&](DbgValueInst *DVI) {
586       assert(DVI->getVariable()->getName() == "2");
587       return DVI->getExpression()->getElements() == Ops;
588     });
589   };
590 
591   // Case 1: The original expr is empty, so no deref is needed.
592   EXPECT_TRUE(hasADbgVal({DW_OP_dup, DW_OP_constu, 31, DW_OP_shr, DW_OP_lit0,
593                           DW_OP_not, DW_OP_mul, DW_OP_or, DW_OP_stack_value}));
594 
595   // Case 2: Perform an address calculation with the original expr, deref it,
596   // then sign-extend the result.
597   EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref, DW_OP_dup,
598                           DW_OP_constu, 31, DW_OP_shr, DW_OP_lit0, DW_OP_not,
599                           DW_OP_mul, DW_OP_or, DW_OP_stack_value}));
600 
601   // Case 3: Insert the sign-extension logic before the DW_OP_stack_value.
602   EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_dup, DW_OP_constu, 31,
603                           DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_or,
604                           DW_OP_stack_value}));
605 
606   // Cases 4-6: Just like cases 1-3, but preserve the fragment at the end.
607   EXPECT_TRUE(hasADbgVal({DW_OP_dup, DW_OP_constu, 31, DW_OP_shr, DW_OP_lit0,
608                           DW_OP_not, DW_OP_mul, DW_OP_or, DW_OP_stack_value,
609                           DW_OP_LLVM_fragment, 0, 8}));
610   EXPECT_TRUE(
611       hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref, DW_OP_dup, DW_OP_constu,
612                   31, DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_or,
613                   DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
614   EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_dup, DW_OP_constu, 31,
615                           DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_or,
616                           DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
617 
618   verifyModule(*M, &errs(), &BrokenDebugInfo);
619   ASSERT_FALSE(BrokenDebugInfo);
620 }
621