xref: /llvm-project/llvm/unittests/CodeGen/InstrRefLDVTest.cpp (revision 63e1647827f3427c5f3ad37461d84a63ba5fcdaf)
1 //===------------- llvm/unittest/CodeGen/InstrRefLDVTest.cpp --------------===//
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/CodeGen/MIRParser/MIRParser.h"
10 #include "llvm/CodeGen/MachineDominators.h"
11 #include "llvm/CodeGen/MachineModuleInfo.h"
12 #include "llvm/CodeGen/TargetFrameLowering.h"
13 #include "llvm/CodeGen/TargetInstrInfo.h"
14 #include "llvm/CodeGen/TargetLowering.h"
15 #include "llvm/CodeGen/TargetRegisterInfo.h"
16 #include "llvm/CodeGen/TargetSubtargetInfo.h"
17 #include "llvm/IR/DIBuilder.h"
18 #include "llvm/IR/DebugInfoMetadata.h"
19 #include "llvm/IR/IRBuilder.h"
20 #include "llvm/IR/Module.h"
21 #include "llvm/MC/TargetRegistry.h"
22 #include "llvm/Support/MemoryBuffer.h"
23 #include "llvm/Support/TargetSelect.h"
24 #include "llvm/Target/TargetMachine.h"
25 #include "llvm/Target/TargetOptions.h"
26 
27 #include "../lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h"
28 
29 #include "gtest/gtest.h"
30 
31 using namespace llvm;
32 using namespace LiveDebugValues;
33 
34 // Include helper functions to ease the manipulation of MachineFunctions
35 #include "MFCommon.inc"
36 
37 class InstrRefLDVTest : public testing::Test {
38 public:
39   friend class InstrRefBasedLDV;
40   using MLocTransferMap = InstrRefBasedLDV::MLocTransferMap;
41 
42   LLVMContext Ctx;
43   std::unique_ptr<Module> Mod;
44   std::unique_ptr<TargetMachine> Machine;
45   std::unique_ptr<MachineFunction> MF;
46   std::unique_ptr<MachineDominatorTree> DomTree;
47   std::unique_ptr<MachineModuleInfo> MMI;
48   DICompileUnit *OurCU;
49   DIFile *OurFile;
50   DISubprogram *OurFunc;
51   DILexicalBlock *OurBlock, *AnotherBlock;
52   DISubprogram *ToInlineFunc;
53   DILexicalBlock *ToInlineBlock;
54   DILocalVariable *FuncVariable;
55   DIBasicType *LongInt;
56   DIExpression *EmptyExpr;
57   LiveDebugValues::OverlapMap Overlaps;
58   LiveDebugValues::DebugVariableMap DVMap;
59 
60   DebugLoc OutermostLoc, InBlockLoc, NotNestedBlockLoc, InlinedLoc;
61 
62   MachineBasicBlock *MBB0, *MBB1, *MBB2, *MBB3, *MBB4;
63 
64   std::unique_ptr<InstrRefBasedLDV> LDV;
65   std::unique_ptr<MLocTracker> MTracker;
66   std::unique_ptr<VLocTracker> VTracker;
67 
68   SmallString<256> MIRStr;
69 
70   InstrRefLDVTest() : Ctx(), Mod(std::make_unique<Module>("beehives", Ctx)) {}
71 
72   void SetUp() {
73     // Boilerplate that creates a MachineFunction and associated blocks.
74 
75     Mod->setDataLayout("e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-"
76                        "f80:128-n8:16:32:64-S128");
77     Triple TargetTriple("x86_64--");
78     std::string Error;
79     const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
80     if (!T)
81       GTEST_SKIP();
82 
83     TargetOptions Options;
84     Machine = std::unique_ptr<TargetMachine>(T->createTargetMachine(
85         Triple::normalize("x86_64--"), "", "", Options, std::nullopt,
86         std::nullopt, CodeGenOptLevel::Aggressive));
87 
88     auto Type = FunctionType::get(Type::getVoidTy(Ctx), false);
89     auto F =
90         Function::Create(Type, GlobalValue::ExternalLinkage, "Test", &*Mod);
91 
92     unsigned FunctionNum = 42;
93     MMI = std::make_unique<MachineModuleInfo>((LLVMTargetMachine *)&*Machine);
94     const TargetSubtargetInfo &STI = *Machine->getSubtargetImpl(*F);
95 
96     MF = std::make_unique<MachineFunction>(*F, (LLVMTargetMachine &)*Machine,
97                                            STI, MMI->getContext(), FunctionNum);
98 
99     // Create metadata: CU, subprogram, some blocks and an inline function
100     // scope.
101     DIBuilder DIB(*Mod);
102     OurFile = DIB.createFile("xyzzy.c", "/cave");
103     OurCU =
104         DIB.createCompileUnit(dwarf::DW_LANG_C99, OurFile, "nou", false, "", 0);
105     auto OurSubT =
106         DIB.createSubroutineType(DIB.getOrCreateTypeArray(std::nullopt));
107     OurFunc =
108         DIB.createFunction(OurCU, "bees", "", OurFile, 1, OurSubT, 1,
109                            DINode::FlagZero, DISubprogram::SPFlagDefinition);
110     F->setSubprogram(OurFunc);
111     OurBlock = DIB.createLexicalBlock(OurFunc, OurFile, 2, 3);
112     AnotherBlock = DIB.createLexicalBlock(OurFunc, OurFile, 2, 6);
113     ToInlineFunc =
114         DIB.createFunction(OurFile, "shoes", "", OurFile, 10, OurSubT, 10,
115                            DINode::FlagZero, DISubprogram::SPFlagDefinition);
116 
117     // Make some nested scopes.
118     OutermostLoc = DILocation::get(Ctx, 3, 1, OurFunc);
119     InBlockLoc = DILocation::get(Ctx, 4, 1, OurBlock);
120     InlinedLoc = DILocation::get(Ctx, 10, 1, ToInlineFunc, InBlockLoc.get());
121 
122     // Make a scope that isn't nested within the others.
123     NotNestedBlockLoc = DILocation::get(Ctx, 4, 1, AnotherBlock);
124 
125     LongInt = DIB.createBasicType("long", 64, llvm::dwarf::DW_ATE_unsigned);
126     FuncVariable = DIB.createAutoVariable(OurFunc, "lala", OurFile, 1, LongInt);
127     EmptyExpr = DIExpression::get(Ctx, {});
128 
129     DIB.finalize();
130   }
131 
132   Register getRegByName(const char *WantedName) {
133     auto *TRI = MF->getRegInfo().getTargetRegisterInfo();
134     // Slow, but works.
135     for (unsigned int I = 1; I < TRI->getNumRegs(); ++I) {
136       const char *Name = TRI->getName(I);
137       if (strcmp(WantedName, Name) == 0)
138         return I;
139     }
140 
141     // If this ever fails, something is very wrong with this unit test.
142     llvm_unreachable("Can't find register by name");
143   }
144 
145   InstrRefBasedLDV *setupLDVObj(MachineFunction *MF) {
146     // Create a new LDV object, and plug some relevant object ptrs into it.
147     LDV = std::make_unique<InstrRefBasedLDV>();
148     const TargetSubtargetInfo &STI = MF->getSubtarget();
149     LDV->TII = STI.getInstrInfo();
150     LDV->TRI = STI.getRegisterInfo();
151     LDV->TFI = STI.getFrameLowering();
152     LDV->MFI = &MF->getFrameInfo();
153     LDV->MRI = &MF->getRegInfo();
154 
155     DomTree = std::make_unique<MachineDominatorTree>(*MF);
156     LDV->DomTree = &*DomTree;
157 
158     // Future work: unit tests for mtracker / vtracker / ttracker.
159 
160     // Setup things like the artifical block map, and BlockNo <=> RPO Order
161     // mappings.
162     LDV->initialSetup(*MF);
163     LDV->LS.initialize(*MF);
164     addMTracker(MF);
165     return &*LDV;
166   }
167 
168   void addMTracker(MachineFunction *MF) {
169     ASSERT_TRUE(LDV);
170     // Add a machine-location-tracking object to LDV. Don't initialize any
171     // register locations within it though.
172     const TargetSubtargetInfo &STI = MF->getSubtarget();
173     MTracker = std::make_unique<MLocTracker>(
174           *MF, *LDV->TII, *LDV->TRI, *STI.getTargetLowering());
175     LDV->MTracker = &*MTracker;
176   }
177 
178   void addVTracker() {
179     ASSERT_TRUE(LDV);
180     VTracker = std::make_unique<VLocTracker>(DVMap, Overlaps, EmptyExpr);
181     LDV->VTracker = &*VTracker;
182   }
183 
184   DbgOpID addValueDbgOp(ValueIDNum V) {
185     return LDV->DbgOpStore.insert(DbgOp(V));
186   }
187   DbgOpID addConstDbgOp(MachineOperand MO) {
188     return LDV->DbgOpStore.insert(DbgOp(MO));
189   }
190 
191   // Some routines for bouncing into LDV,
192   void buildMLocValueMap(FuncValueTable &MInLocs, FuncValueTable &MOutLocs,
193                          SmallVectorImpl<MLocTransferMap> &MLocTransfer) {
194     LDV->buildMLocValueMap(*MF, MInLocs, MOutLocs, MLocTransfer);
195   }
196 
197   void placeMLocPHIs(MachineFunction &MF,
198                      SmallPtrSetImpl<MachineBasicBlock *> &AllBlocks,
199                      FuncValueTable &MInLocs,
200                      SmallVectorImpl<MLocTransferMap> &MLocTransfer) {
201     LDV->placeMLocPHIs(MF, AllBlocks, MInLocs, MLocTransfer);
202   }
203 
204   bool
205   pickVPHILoc(SmallVectorImpl<DbgOpID> &OutValues, const MachineBasicBlock &MBB,
206               const InstrRefBasedLDV::LiveIdxT &LiveOuts,
207               FuncValueTable &MOutLocs,
208               const SmallVectorImpl<const MachineBasicBlock *> &BlockOrders) {
209     return LDV->pickVPHILoc(OutValues, MBB, LiveOuts, MOutLocs, BlockOrders);
210   }
211 
212   bool vlocJoin(MachineBasicBlock &MBB, InstrRefBasedLDV::LiveIdxT &VLOCOutLocs,
213                 SmallPtrSet<const MachineBasicBlock *, 8> &BlocksToExplore,
214                 DbgValue &InLoc) {
215     return LDV->vlocJoin(MBB, VLOCOutLocs, BlocksToExplore, InLoc);
216   }
217 
218   void buildVLocValueMap(const DILocation *DILoc,
219                     const SmallSet<DebugVariableID, 4> &VarsWeCareAbout,
220                     SmallPtrSetImpl<MachineBasicBlock *> &AssignBlocks,
221                     InstrRefBasedLDV::LiveInsT &Output, FuncValueTable &MOutLocs,
222                     FuncValueTable &MInLocs,
223                     SmallVectorImpl<VLocTracker> &AllTheVLocs) {
224     LDV->buildVLocValueMap(DILoc, VarsWeCareAbout, AssignBlocks, Output,
225                            MOutLocs, MInLocs, AllTheVLocs);
226   }
227 
228   void initValueArray(FuncValueTable &Nums, unsigned Blks, unsigned Locs) {
229     for (unsigned int I = 0; I < Blks; ++I)
230       for (unsigned int J = 0; J < Locs; ++J)
231         Nums[I][J] = ValueIDNum::EmptyValue;
232   }
233 
234   void setupSingleBlock() {
235     // Add an entry block with nothing but 'ret void' in it.
236     Function &F = const_cast<llvm::Function &>(MF->getFunction());
237     auto *BB0 = BasicBlock::Create(Ctx, "entry", &F);
238     IRBuilder<> IRB(BB0);
239     IRB.CreateRetVoid();
240     MBB0 = MF->CreateMachineBasicBlock(BB0);
241     MF->insert(MF->end(), MBB0);
242     MF->RenumberBlocks();
243 
244     setupLDVObj(&*MF);
245   }
246 
247   void setupDiamondBlocks() {
248     //        entry
249     //        /  \
250     //      br1  br2
251     //        \  /
252     //         ret
253     llvm::Function &F = const_cast<llvm::Function &>(MF->getFunction());
254     auto *BB0 = BasicBlock::Create(Ctx, "a", &F);
255     auto *BB1 = BasicBlock::Create(Ctx, "b", &F);
256     auto *BB2 = BasicBlock::Create(Ctx, "c", &F);
257     auto *BB3 = BasicBlock::Create(Ctx, "d", &F);
258     IRBuilder<> IRB0(BB0), IRB1(BB1), IRB2(BB2), IRB3(BB3);
259     IRB0.CreateBr(BB1);
260     IRB1.CreateBr(BB2);
261     IRB2.CreateBr(BB3);
262     IRB3.CreateRetVoid();
263     MBB0 = MF->CreateMachineBasicBlock(BB0);
264     MF->insert(MF->end(), MBB0);
265     MBB1 = MF->CreateMachineBasicBlock(BB1);
266     MF->insert(MF->end(), MBB1);
267     MBB2 = MF->CreateMachineBasicBlock(BB2);
268     MF->insert(MF->end(), MBB2);
269     MBB3 = MF->CreateMachineBasicBlock(BB3);
270     MF->insert(MF->end(), MBB3);
271     MBB0->addSuccessor(MBB1);
272     MBB0->addSuccessor(MBB2);
273     MBB1->addSuccessor(MBB3);
274     MBB2->addSuccessor(MBB3);
275     MF->RenumberBlocks();
276 
277     setupLDVObj(&*MF);
278   }
279 
280   void setupSimpleLoop() {
281     //    entry
282     //     |
283     //     |/-----\
284     //    loopblk |
285     //     |\-----/
286     //     |
287     //     ret
288     llvm::Function &F = const_cast<llvm::Function &>(MF->getFunction());
289     auto *BB0 = BasicBlock::Create(Ctx, "entry", &F);
290     auto *BB1 = BasicBlock::Create(Ctx, "loop", &F);
291     auto *BB2 = BasicBlock::Create(Ctx, "ret", &F);
292     IRBuilder<> IRB0(BB0), IRB1(BB1), IRB2(BB2);
293     IRB0.CreateBr(BB1);
294     IRB1.CreateBr(BB2);
295     IRB2.CreateRetVoid();
296     MBB0 = MF->CreateMachineBasicBlock(BB0);
297     MF->insert(MF->end(), MBB0);
298     MBB1 = MF->CreateMachineBasicBlock(BB1);
299     MF->insert(MF->end(), MBB1);
300     MBB2 = MF->CreateMachineBasicBlock(BB2);
301     MF->insert(MF->end(), MBB2);
302     MBB0->addSuccessor(MBB1);
303     MBB1->addSuccessor(MBB2);
304     MBB1->addSuccessor(MBB1);
305     MF->RenumberBlocks();
306 
307     setupLDVObj(&*MF);
308   }
309 
310   void setupNestedLoops() {
311     //    entry
312     //     |
313     //    loop1
314     //     ^\
315     //     | \    /-\
316     //     |  loop2  |
317     //     |  /   \-/
318     //     ^ /
319     //     join
320     //     |
321     //     ret
322     llvm::Function &F = const_cast<llvm::Function &>(MF->getFunction());
323     auto *BB0 = BasicBlock::Create(Ctx, "entry", &F);
324     auto *BB1 = BasicBlock::Create(Ctx, "loop1", &F);
325     auto *BB2 = BasicBlock::Create(Ctx, "loop2", &F);
326     auto *BB3 = BasicBlock::Create(Ctx, "join", &F);
327     auto *BB4 = BasicBlock::Create(Ctx, "ret", &F);
328     IRBuilder<> IRB0(BB0), IRB1(BB1), IRB2(BB2), IRB3(BB3), IRB4(BB4);
329     IRB0.CreateBr(BB1);
330     IRB1.CreateBr(BB2);
331     IRB2.CreateBr(BB3);
332     IRB3.CreateBr(BB4);
333     IRB4.CreateRetVoid();
334     MBB0 = MF->CreateMachineBasicBlock(BB0);
335     MF->insert(MF->end(), MBB0);
336     MBB1 = MF->CreateMachineBasicBlock(BB1);
337     MF->insert(MF->end(), MBB1);
338     MBB2 = MF->CreateMachineBasicBlock(BB2);
339     MF->insert(MF->end(), MBB2);
340     MBB3 = MF->CreateMachineBasicBlock(BB3);
341     MF->insert(MF->end(), MBB3);
342     MBB4 = MF->CreateMachineBasicBlock(BB4);
343     MF->insert(MF->end(), MBB4);
344     MBB0->addSuccessor(MBB1);
345     MBB1->addSuccessor(MBB2);
346     MBB2->addSuccessor(MBB2);
347     MBB2->addSuccessor(MBB3);
348     MBB3->addSuccessor(MBB1);
349     MBB3->addSuccessor(MBB4);
350     MF->RenumberBlocks();
351 
352     setupLDVObj(&*MF);
353   }
354 
355   void setupNoDominatingLoop() {
356     //           entry
357     //            / \
358     //           /   \
359     //          /     \
360     //        head1   head2
361     //        ^  \   /   ^
362     //        ^   \ /    ^
363     //        \-joinblk -/
364     //             |
365     //            ret
366     llvm::Function &F = const_cast<llvm::Function &>(MF->getFunction());
367     auto *BB0 = BasicBlock::Create(Ctx, "entry", &F);
368     auto *BB1 = BasicBlock::Create(Ctx, "head1", &F);
369     auto *BB2 = BasicBlock::Create(Ctx, "head2", &F);
370     auto *BB3 = BasicBlock::Create(Ctx, "joinblk", &F);
371     auto *BB4 = BasicBlock::Create(Ctx, "ret", &F);
372     IRBuilder<> IRB0(BB0), IRB1(BB1), IRB2(BB2), IRB3(BB3), IRB4(BB4);
373     IRB0.CreateBr(BB1);
374     IRB1.CreateBr(BB2);
375     IRB2.CreateBr(BB3);
376     IRB3.CreateBr(BB4);
377     IRB4.CreateRetVoid();
378     MBB0 = MF->CreateMachineBasicBlock(BB0);
379     MF->insert(MF->end(), MBB0);
380     MBB1 = MF->CreateMachineBasicBlock(BB1);
381     MF->insert(MF->end(), MBB1);
382     MBB2 = MF->CreateMachineBasicBlock(BB2);
383     MF->insert(MF->end(), MBB2);
384     MBB3 = MF->CreateMachineBasicBlock(BB3);
385     MF->insert(MF->end(), MBB3);
386     MBB4 = MF->CreateMachineBasicBlock(BB4);
387     MF->insert(MF->end(), MBB4);
388     MBB0->addSuccessor(MBB1);
389     MBB0->addSuccessor(MBB2);
390     MBB1->addSuccessor(MBB3);
391     MBB2->addSuccessor(MBB3);
392     MBB3->addSuccessor(MBB1);
393     MBB3->addSuccessor(MBB2);
394     MBB3->addSuccessor(MBB4);
395     MF->RenumberBlocks();
396 
397     setupLDVObj(&*MF);
398   }
399 
400   void setupBadlyNestedLoops() {
401     //           entry
402     //             |
403     //           loop1 -o
404     //             | ^
405     //             | ^
406     //           loop2 -o
407     //             | ^
408     //             | ^
409     //           loop3 -o
410     //             |
411     //            ret
412     //
413     // NB: the loop blocks self-loop, which is a bit too fiddly to draw on
414     // accurately.
415     llvm::Function &F = const_cast<llvm::Function &>(MF->getFunction());
416     auto *BB0 = BasicBlock::Create(Ctx, "entry", &F);
417     auto *BB1 = BasicBlock::Create(Ctx, "loop1", &F);
418     auto *BB2 = BasicBlock::Create(Ctx, "loop2", &F);
419     auto *BB3 = BasicBlock::Create(Ctx, "loop3", &F);
420     auto *BB4 = BasicBlock::Create(Ctx, "ret", &F);
421     IRBuilder<> IRB0(BB0), IRB1(BB1), IRB2(BB2), IRB3(BB3), IRB4(BB4);
422     IRB0.CreateBr(BB1);
423     IRB1.CreateBr(BB2);
424     IRB2.CreateBr(BB3);
425     IRB3.CreateBr(BB4);
426     IRB4.CreateRetVoid();
427     MBB0 = MF->CreateMachineBasicBlock(BB0);
428     MF->insert(MF->end(), MBB0);
429     MBB1 = MF->CreateMachineBasicBlock(BB1);
430     MF->insert(MF->end(), MBB1);
431     MBB2 = MF->CreateMachineBasicBlock(BB2);
432     MF->insert(MF->end(), MBB2);
433     MBB3 = MF->CreateMachineBasicBlock(BB3);
434     MF->insert(MF->end(), MBB3);
435     MBB4 = MF->CreateMachineBasicBlock(BB4);
436     MF->insert(MF->end(), MBB4);
437     MBB0->addSuccessor(MBB1);
438     MBB1->addSuccessor(MBB1);
439     MBB1->addSuccessor(MBB2);
440     MBB2->addSuccessor(MBB1);
441     MBB2->addSuccessor(MBB2);
442     MBB2->addSuccessor(MBB3);
443     MBB3->addSuccessor(MBB2);
444     MBB3->addSuccessor(MBB3);
445     MBB3->addSuccessor(MBB4);
446     MF->RenumberBlocks();
447 
448     setupLDVObj(&*MF);
449   }
450 
451   MachineFunction *readMIRBlock(const char *Input) {
452     MIRStr.clear();
453     StringRef S = Twine(Twine(R"MIR(
454 --- |
455   target triple = "x86_64-unknown-linux-gnu"
456   define void @test() { ret void }
457 ...
458 ---
459 name: test
460 tracksRegLiveness: true
461 stack:
462   - { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 8,
463       stack-id: default, callee-saved-register: '', callee-saved-restored: true,
464       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
465 body:  |
466    bb.0:
467     liveins: $rdi, $rsi
468 )MIR") + Twine(Input) + Twine("...\n"))
469                       .toNullTerminatedStringRef(MIRStr);
470     ;
471 
472     // Clear the "test" function from MMI if it's still present.
473     if (Function *Fn = Mod->getFunction("test"))
474       MMI->deleteMachineFunctionFor(*Fn);
475 
476     auto MemBuf = MemoryBuffer::getMemBuffer(S, "<input>");
477     auto MIRParse = createMIRParser(std::move(MemBuf), Ctx);
478     Mod = MIRParse->parseIRModule();
479     assert(Mod);
480     Mod->setDataLayout("e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-"
481                        "f80:128-n8:16:32:64-S128");
482 
483     bool Result = MIRParse->parseMachineFunctions(*Mod, *MMI);
484     assert(!Result && "Failed to parse unit test machine function?");
485     (void)Result;
486 
487     Function *Fn = Mod->getFunction("test");
488     assert(Fn && "Failed to parse a unit test module string?");
489     Fn->setSubprogram(OurFunc);
490     return MMI->getMachineFunction(*Fn);
491   }
492 
493   void
494   produceMLocTransferFunction(MachineFunction &MF,
495                               SmallVectorImpl<MLocTransferMap> &MLocTransfer,
496                               unsigned MaxNumBlocks) {
497     LDV->produceMLocTransferFunction(MF, MLocTransfer, MaxNumBlocks);
498   }
499 
500   std::pair<FuncValueTable, FuncValueTable>
501   allocValueTables(unsigned Blocks, unsigned Locs) {
502     return {FuncValueTable(Blocks, Locs), FuncValueTable(Blocks, Locs)};
503   }
504 };
505 
506 TEST_F(InstrRefLDVTest, MTransferDefs) {
507   MachineFunction *MF = readMIRBlock(
508    "    $rax = MOV64ri 0\n"
509    "    RET64 $rax\n");
510   setupLDVObj(MF);
511 
512   // We should start with only SP tracked.
513   EXPECT_TRUE(MTracker->getNumLocs() == 1);
514 
515   SmallVector<MLocTransferMap, 1> TransferMap;
516   TransferMap.resize(1);
517   produceMLocTransferFunction(*MF, TransferMap, 1);
518 
519   // Code contains only one register write: that should assign to each of the
520   // aliasing registers. Test that all of them get locations, and have a
521   // corresponding def at the first instr in the function.
522   const char *RegNames[] = {"RAX", "HAX", "EAX", "AX", "AH", "AL"};
523   EXPECT_TRUE(MTracker->getNumLocs() == 7);
524   for (const char *RegName : RegNames) {
525     Register R = getRegByName(RegName);
526     ASSERT_TRUE(MTracker->isRegisterTracked(R));
527     LocIdx L = MTracker->getRegMLoc(R);
528     ValueIDNum V = MTracker->readReg(R);
529     // Value of this register should be: block zero, instruction 1, and the
530     // location it's defined in is itself.
531     ValueIDNum ToCmp(0, 1, L);
532     EXPECT_EQ(V, ToCmp);
533   }
534 
535   // Do the same again, but with an aliasing write. This should write to all
536   // the same registers again, except $ah and $hax (the upper 8 bits of $ax
537   // and 32 bits of $rax resp.).
538   MF = readMIRBlock(
539    "    $rax = MOV64ri 0\n"
540    "    $al = MOV8ri 0\n"
541    "    RET64 $rax\n");
542   setupLDVObj(MF);
543   TransferMap.clear();
544   TransferMap.resize(1);
545   produceMLocTransferFunction(*MF, TransferMap, 1);
546 
547   auto TestRegSetSite = [&](const char *Name, unsigned InstrNum) {
548     Register R = getRegByName(Name);
549     ASSERT_TRUE(MTracker->isRegisterTracked(R));
550     LocIdx L = MTracker->getRegMLoc(R);
551     ValueIDNum V = MTracker->readMLoc(L);
552     ValueIDNum ToCmp(0, InstrNum, L);
553     EXPECT_EQ(V, ToCmp);
554   };
555 
556   TestRegSetSite("AL", 2);
557   TestRegSetSite("AH", 1);
558   TestRegSetSite("AX", 2);
559   TestRegSetSite("EAX", 2);
560   TestRegSetSite("HAX", 1);
561   TestRegSetSite("RAX", 2);
562 
563   // This call should:
564   //  * Def rax via the implicit-def,
565   //  * Clobber rsi/rdi and all their subregs, via the register mask
566   //  * Same for rcx, despite it not being a use in the instr, it's in the mask
567   //  * NOT clobber $rsp / $esp $ sp, LiveDebugValues deliberately ignores
568   //    these.
569   //  * NOT clobber $rbx, because it's non-volatile
570   //  * Not track every other register in the machine, only those needed.
571  MF = readMIRBlock(
572    "    $rax = MOV64ri 0\n" // instr 1
573    "    $rbx = MOV64ri 0\n" // instr 2
574    "    $rcx = MOV64ri 0\n" // instr 3
575    "    $rdi = MOV64ri 0\n" // instr 4
576    "    $rsi = MOV64ri 0\n" // instr 5
577    "    CALL64r $rax, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit-def $rsp, implicit-def $ssp, implicit-def $rax, implicit-def $esp, implicit-def $sp\n\n\n\n" // instr 6
578    "    RET64 $rax\n"); // instr 7
579   setupLDVObj(MF);
580   TransferMap.clear();
581   TransferMap.resize(1);
582   produceMLocTransferFunction(*MF, TransferMap, 1);
583 
584   const char *RegsSetInCall[] = {"AL",  "AH",  "AX", "EAX", "HAX", "RAX",
585                                  "DIL", "DIH", "DI", "EDI", "HDI", "RDI",
586                                  "SIL", "SIH", "SI", "ESI", "HSI", "RSI",
587                                  "CL",  "CH",  "CX", "ECX", "HCX", "RCX"};
588   for (const char *RegSetInCall : RegsSetInCall)
589     TestRegSetSite(RegSetInCall, 6);
590 
591   const char *RegsLeftAlone[] = {"BL", "BH", "BX", "EBX", "HBX", "RBX"};
592   for (const char *RegLeftAlone : RegsLeftAlone)
593     TestRegSetSite(RegLeftAlone, 2);
594 
595   // Stack pointer should be the live-in to the function, instruction zero.
596   TestRegSetSite("RSP", 0);
597   // These stack regs should not be tracked either. Nor the (fake) subregs.
598   EXPECT_FALSE(MTracker->isRegisterTracked(getRegByName("ESP")));
599   EXPECT_FALSE(MTracker->isRegisterTracked(getRegByName("SP")));
600   EXPECT_FALSE(MTracker->isRegisterTracked(getRegByName("SPL")));
601   EXPECT_FALSE(MTracker->isRegisterTracked(getRegByName("SPH")));
602   EXPECT_FALSE(MTracker->isRegisterTracked(getRegByName("HSP")));
603 
604   // Should only be tracking: 6 x {A, B, C, DI, SI} registers = 30,
605   // Plus RSP, SSP = 32.
606   EXPECT_EQ(32u, MTracker->getNumLocs());
607 
608 
609   // When we DBG_PHI something, we should track all its subregs.
610   MF = readMIRBlock(
611    "    DBG_PHI $rdi, 0\n"
612    "    RET64\n");
613   setupLDVObj(MF);
614   TransferMap.clear();
615   TransferMap.resize(1);
616   produceMLocTransferFunction(*MF, TransferMap, 1);
617 
618   // All DI regs and RSP tracked.
619   EXPECT_EQ(7u, MTracker->getNumLocs());
620 
621   // All the DI registers should have block live-in values, i.e. the argument
622   // to the function.
623   const char *DIRegs[] = {"DIL", "DIH", "DI", "EDI", "HDI", "RDI"};
624   for (const char *DIReg : DIRegs)
625     TestRegSetSite(DIReg, 0);
626 }
627 
628 TEST_F(InstrRefLDVTest, MTransferMeta) {
629   // Meta instructions should not have any effect on register values.
630   SmallVector<MLocTransferMap, 1> TransferMap;
631   MachineFunction *MF = readMIRBlock(
632    "    $rax = MOV64ri 0\n"
633    "    $rax = IMPLICIT_DEF\n"
634    "    $rax = KILL killed $rax\n"
635    "    RET64 $rax\n");
636   setupLDVObj(MF);
637   TransferMap.clear();
638   TransferMap.resize(1);
639   produceMLocTransferFunction(*MF, TransferMap, 1);
640 
641   LocIdx RaxLoc = MTracker->getRegMLoc(getRegByName("RAX"));
642   ValueIDNum V = MTracker->readMLoc(RaxLoc);
643   // Def of rax should be from instruction 1, i.e., unmodified.
644   ValueIDNum Cmp(0, 1, RaxLoc);
645   EXPECT_EQ(Cmp, V);
646 }
647 
648 TEST_F(InstrRefLDVTest, MTransferCopies) {
649   SmallVector<MLocTransferMap, 1> TransferMap;
650   // This memory spill should be recognised, and a spill slot created.
651   MachineFunction *MF = readMIRBlock(
652    "    $rax = MOV64ri 0\n"
653    "    MOV64mr $rsp, 1, $noreg, 16, $noreg, $rax :: (store 8 into %stack.0)\n"
654    "    RET64 $rax\n");
655   setupLDVObj(MF);
656   TransferMap.clear();
657   TransferMap.resize(1);
658   produceMLocTransferFunction(*MF, TransferMap, 1);
659 
660   // Check that the spill location contains the value defined in rax by
661   // instruction 1. The MIR header says -16 offset, but it's stored as -8;
662   // it's not completely clear why, but here we only care about correctly
663   // identifying the slot, not that all the surrounding data is correct.
664   SpillLoc L = {getRegByName("RSP"), StackOffset::getFixed(-8)};
665   SpillLocationNo SpillNo = *MTracker->getOrTrackSpillLoc(L);
666   unsigned SpillLocID = MTracker->getLocID(SpillNo, {64, 0});
667   LocIdx SpillLoc = MTracker->getSpillMLoc(SpillLocID);
668   ValueIDNum V = MTracker->readMLoc(SpillLoc);
669   Register RAX = getRegByName("RAX");
670   LocIdx RaxLoc = MTracker->getRegMLoc(RAX);
671   ValueIDNum Cmp(0, 1, RaxLoc);
672   EXPECT_EQ(V, Cmp);
673 
674   // A spill and restore should be recognised.
675   MF = readMIRBlock(
676    "    $rax = MOV64ri 0\n"
677    "    MOV64mr $rsp, 1, $noreg, 16, $noreg, $rax :: (store 8 into %stack.0)\n"
678    "    $rbx = MOV64rm $rsp, 1, $noreg, 0, $noreg :: (load 8 from %stack.0)\n"
679    "    RET64\n");
680   setupLDVObj(MF);
681   TransferMap.clear();
682   TransferMap.resize(1);
683   produceMLocTransferFunction(*MF, TransferMap, 1);
684 
685   // Test that rbx contains rax from instruction 1.
686   RAX = getRegByName("RAX");
687   RaxLoc = MTracker->getRegMLoc(RAX);
688   Register RBX = getRegByName("RBX");
689   LocIdx RbxLoc = MTracker->getRegMLoc(RBX);
690   Cmp = ValueIDNum(0, 1, RaxLoc);
691   ValueIDNum RbxVal = MTracker->readMLoc(RbxLoc);
692   EXPECT_EQ(RbxVal, Cmp);
693 
694   // Testing that all the subregisters are transferred happens in
695   // MTransferSubregSpills.
696 
697   // Copies and x86 movs should be recognised and honoured. In addition, all
698   // of the subregisters should be copied across too.
699   MF = readMIRBlock(
700    "    $rax = MOV64ri 0\n"
701    "    $rcx = COPY $rax\n"
702    "    $rbx = MOV64rr $rcx\n"
703    "    RET64\n");
704   setupLDVObj(MF);
705   TransferMap.clear();
706   TransferMap.resize(1);
707   produceMLocTransferFunction(*MF, TransferMap, 1);
708 
709   const char *ARegs[] = {"AL", "AH", "AX", "EAX", "HAX", "RAX"};
710   const char *BRegs[] = {"BL", "BH", "BX", "EBX", "HBX", "RBX"};
711   const char *CRegs[] = {"CL", "CH", "CX", "ECX", "HCX", "RCX"};
712   auto CheckReg = [&](unsigned int I) {
713     LocIdx A = MTracker->getRegMLoc(getRegByName(ARegs[I]));
714     LocIdx B = MTracker->getRegMLoc(getRegByName(BRegs[I]));
715     LocIdx C = MTracker->getRegMLoc(getRegByName(CRegs[I]));
716     ValueIDNum ARefVal(0, 1, A);
717     ValueIDNum AVal = MTracker->readMLoc(A);
718     ValueIDNum BVal = MTracker->readMLoc(B);
719     ValueIDNum CVal = MTracker->readMLoc(C);
720     EXPECT_EQ(ARefVal, AVal);
721     EXPECT_EQ(ARefVal, BVal);
722     EXPECT_EQ(ARefVal, CVal);
723   };
724 
725   for (unsigned int I = 0; I < 6; ++I)
726     CheckReg(I);
727 
728   // When we copy to a subregister, the super-register should be def'd too: it's
729   // value will have changed.
730   MF = readMIRBlock(
731    "    $rax = MOV64ri 0\n"
732    "    $ecx = COPY $eax\n"
733    "    RET64\n");
734   setupLDVObj(MF);
735   TransferMap.clear();
736   TransferMap.resize(1);
737   produceMLocTransferFunction(*MF, TransferMap, 1);
738 
739   // First four regs [al, ah, ax, eax] should be copied to *cx.
740   for (unsigned int I = 0; I < 4; ++I) {
741     LocIdx A = MTracker->getRegMLoc(getRegByName(ARegs[I]));
742     LocIdx C = MTracker->getRegMLoc(getRegByName(CRegs[I]));
743     ValueIDNum ARefVal(0, 1, A);
744     ValueIDNum AVal = MTracker->readMLoc(A);
745     ValueIDNum CVal = MTracker->readMLoc(C);
746     EXPECT_EQ(ARefVal, AVal);
747     EXPECT_EQ(ARefVal, CVal);
748   }
749 
750   // But rcx should contain a value defined by the COPY.
751   LocIdx RcxLoc = MTracker->getRegMLoc(getRegByName("RCX"));
752   ValueIDNum RcxVal = MTracker->readMLoc(RcxLoc);
753   ValueIDNum RcxDefVal(0, 2, RcxLoc); // instr 2 -> the copy
754   EXPECT_EQ(RcxVal, RcxDefVal);
755 }
756 
757 TEST_F(InstrRefLDVTest, MTransferSubregSpills) {
758   SmallVector<MLocTransferMap, 1> TransferMap;
759   MachineFunction *MF = readMIRBlock(
760    "    $rax = MOV64ri 0\n"
761    "    MOV64mr $rsp, 1, $noreg, 16, $noreg, $rax :: (store 8 into %stack.0)\n"
762    "    $rbx = MOV64rm $rsp, 1, $noreg, 0, $noreg :: (load 8 from %stack.0)\n"
763    "    RET64\n");
764   setupLDVObj(MF);
765   TransferMap.clear();
766   TransferMap.resize(1);
767   produceMLocTransferFunction(*MF, TransferMap, 1);
768 
769   // Check that all the subregs of rax and rbx contain the same values. One
770   // should completely transfer to the other.
771   const char *ARegs[] = {"AL", "AH", "AX", "EAX", "HAX", "RAX"};
772   const char *BRegs[] = {"BL", "BH", "BX", "EBX", "HBX", "RBX"};
773   for (unsigned int I = 0; I < 6; ++I) {
774     LocIdx A = MTracker->getRegMLoc(getRegByName(ARegs[I]));
775     LocIdx B = MTracker->getRegMLoc(getRegByName(BRegs[I]));
776     EXPECT_EQ(MTracker->readMLoc(A), MTracker->readMLoc(B));
777   }
778 
779   // Explicitly check what's in the different subreg slots, on the stack.
780   // Pair up subreg idx fields with the corresponding subregister in $rax.
781   MLocTracker::StackSlotPos SubRegIdxes[] = {{8, 0}, {8, 8}, {16, 0}, {32, 0}, {64, 0}};
782   const char *SubRegNames[] = {"AL", "AH", "AX", "EAX", "RAX"};
783   for (unsigned int I = 0; I < 5; ++I) {
784     // Value number where it's defined,
785     LocIdx RegLoc = MTracker->getRegMLoc(getRegByName(SubRegNames[I]));
786     ValueIDNum DefNum(0, 1, RegLoc);
787     // Read the corresponding subreg field from the stack.
788     SpillLoc L = {getRegByName("RSP"), StackOffset::getFixed(-8)};
789     SpillLocationNo SpillNo = *MTracker->getOrTrackSpillLoc(L);
790     unsigned SpillID = MTracker->getLocID(SpillNo, SubRegIdxes[I]);
791     LocIdx SpillLoc = MTracker->getSpillMLoc(SpillID);
792     ValueIDNum SpillValue = MTracker->readMLoc(SpillLoc);
793     EXPECT_EQ(DefNum, SpillValue);
794   }
795 
796   // If we have exactly the same code, but we write $eax to the stack slot after
797   // $rax, then we should still have exactly the same output in the lower five
798   // subregisters. Storing $eax to the start of the slot will overwrite with the
799   // same values. $rax, as an aliasing register, should be reset to something
800   // else by that write.
801   // In theory, we could try and recognise that we're writing the _same_ values
802   // to the stack again, and so $rax doesn't need to be reset to something else.
803   // It seems vanishingly unlikely that LLVM would generate such code though,
804   // so the benefits would be small.
805   MF = readMIRBlock(
806    "    $rax = MOV64ri 0\n"
807    "    MOV64mr $rsp, 1, $noreg, 16, $noreg, $rax :: (store 8 into %stack.0)\n"
808    "    MOV32mr $rsp, 1, $noreg, 16, $noreg, $eax :: (store 4 into %stack.0)\n"
809    "    $rbx = MOV64rm $rsp, 1, $noreg, 0, $noreg :: (load 8 from %stack.0)\n"
810    "    RET64\n");
811   setupLDVObj(MF);
812   TransferMap.clear();
813   TransferMap.resize(1);
814   produceMLocTransferFunction(*MF, TransferMap, 1);
815 
816   // Check lower five registers up to and include $eax == $ebx,
817   for (unsigned int I = 0; I < 5; ++I) {
818     LocIdx A = MTracker->getRegMLoc(getRegByName(ARegs[I]));
819     LocIdx B = MTracker->getRegMLoc(getRegByName(BRegs[I]));
820     EXPECT_EQ(MTracker->readMLoc(A), MTracker->readMLoc(B));
821   }
822 
823   // $rbx should contain something else; today it's a def at the spill point
824   // of the 4 byte value.
825   SpillLoc L = {getRegByName("RSP"), StackOffset::getFixed(-8)};
826   SpillLocationNo SpillNo = *MTracker->getOrTrackSpillLoc(L);
827   unsigned SpillID = MTracker->getLocID(SpillNo, {64, 0});
828   LocIdx Spill64Loc = MTracker->getSpillMLoc(SpillID);
829   ValueIDNum DefAtSpill64(0, 3, Spill64Loc);
830   LocIdx RbxLoc = MTracker->getRegMLoc(getRegByName("RBX"));
831   EXPECT_EQ(MTracker->readMLoc(RbxLoc), DefAtSpill64);
832 
833   // Same again, test that the lower four subreg slots on the stack are the
834   // value defined by $rax in instruction 1.
835   for (unsigned int I = 0; I < 4; ++I) {
836     // Value number where it's defined,
837     LocIdx RegLoc = MTracker->getRegMLoc(getRegByName(SubRegNames[I]));
838     ValueIDNum DefNum(0, 1, RegLoc);
839     // Read the corresponding subreg field from the stack.
840     SpillNo = *MTracker->getOrTrackSpillLoc(L);
841     SpillID = MTracker->getLocID(SpillNo, SubRegIdxes[I]);
842     LocIdx SpillLoc = MTracker->getSpillMLoc(SpillID);
843     ValueIDNum SpillValue = MTracker->readMLoc(SpillLoc);
844     EXPECT_EQ(DefNum, SpillValue);
845   }
846 
847   // Stack slot for $rax should be a different value, today it's EmptyValue.
848   ValueIDNum SpillValue = MTracker->readMLoc(Spill64Loc);
849   EXPECT_EQ(SpillValue, DefAtSpill64);
850 
851   // If we write something to the stack, then over-write with some register
852   // from a completely different hierarchy, none of the "old" values should be
853   // readable.
854   // NB: slight hack, store 16 in to a 8 byte stack slot.
855   MF = readMIRBlock(
856    "    $rax = MOV64ri 0\n"
857    "    MOV64mr $rsp, 1, $noreg, 16, $noreg, $rax :: (store 8 into %stack.0)\n"
858    "    $xmm0 = IMPLICIT_DEF\n"
859    "    MOVUPDmr $rsp, 1, $noreg, 16, $noreg, killed $xmm0 :: (store (s128) into %stack.0)\n"
860    "    $rbx = MOV64rm $rsp, 1, $noreg, 0, $noreg :: (load 8 from %stack.0)\n"
861    "    RET64\n");
862   setupLDVObj(MF);
863   TransferMap.clear();
864   TransferMap.resize(1);
865   produceMLocTransferFunction(*MF, TransferMap, 1);
866 
867   for (unsigned int I = 0; I < 5; ++I) {
868     // Read subreg fields from the stack.
869     SpillLocationNo SpillNo = *MTracker->getOrTrackSpillLoc(L);
870     unsigned SpillID = MTracker->getLocID(SpillNo, SubRegIdxes[I]);
871     LocIdx SpillLoc = MTracker->getSpillMLoc(SpillID);
872     ValueIDNum SpillValue = MTracker->readMLoc(SpillLoc);
873 
874     // Value should be defined by the spill-to-xmm0 instr, get value of a def
875     // at the point of the spill.
876     ValueIDNum SpillDef(0, 4, SpillLoc);
877     EXPECT_EQ(SpillValue, SpillDef);
878   }
879 
880   // Read xmm0's position and ensure it has a value. Should be the live-in
881   // value to the block, as IMPLICIT_DEF isn't a real def.
882   SpillNo = *MTracker->getOrTrackSpillLoc(L);
883   SpillID = MTracker->getLocID(SpillNo, {128, 0});
884   LocIdx Spill128Loc = MTracker->getSpillMLoc(SpillID);
885   SpillValue = MTracker->readMLoc(Spill128Loc);
886   Register XMM0 = getRegByName("XMM0");
887   LocIdx Xmm0Loc = MTracker->getRegMLoc(XMM0);
888   EXPECT_EQ(ValueIDNum(0, 0, Xmm0Loc), SpillValue);
889 
890   // What happens if we spill ah to the stack, then load al? It should find
891   // the same value.
892   MF = readMIRBlock(
893    "    $rax = MOV64ri 0\n"
894    "    MOV8mr $rsp, 1, $noreg, 16, $noreg, $ah :: (store 1 into %stack.0)\n"
895    "    $al = MOV8rm $rsp, 1, $noreg, 0, $noreg :: (load 1 from %stack.0)\n"
896    "    RET64\n");
897   setupLDVObj(MF);
898   TransferMap.clear();
899   TransferMap.resize(1);
900   produceMLocTransferFunction(*MF, TransferMap, 1);
901 
902   Register AL = getRegByName("AL");
903   Register AH = getRegByName("AH");
904   LocIdx AlLoc = MTracker->getRegMLoc(AL);
905   LocIdx AhLoc = MTracker->getRegMLoc(AH);
906   ValueIDNum AHDef(0, 1, AhLoc);
907   ValueIDNum ALValue = MTracker->readMLoc(AlLoc);
908   EXPECT_EQ(ALValue, AHDef);
909 }
910 
911 TEST_F(InstrRefLDVTest, MLocSingleBlock) {
912   // Test some very simple properties about interpreting the transfer function.
913   setupSingleBlock();
914 
915   // We should start with a single location, the stack pointer.
916   ASSERT_TRUE(MTracker->getNumLocs() == 1);
917   LocIdx RspLoc(0);
918 
919   // Set up live-in and live-out tables for this function: two locations (we
920   // add one later) in a single block.
921   auto [MOutLocs, MInLocs] = allocValueTables(1, 2);
922 
923   // Transfer function: nothing.
924   SmallVector<MLocTransferMap, 1> TransferFunc;
925   TransferFunc.resize(1);
926 
927   // Try and build value maps...
928   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
929 
930   // The result should be that RSP is marked as a live-in-PHI -- this represents
931   // an argument. And as there's no transfer function, the block live-out should
932   // be the same.
933   EXPECT_EQ(MInLocs[0][0], ValueIDNum(0, 0, RspLoc));
934   EXPECT_EQ(MOutLocs[0][0], ValueIDNum(0, 0, RspLoc));
935 
936   // Try again, this time initialising the in-locs to be defined by an
937   // instruction. The entry block should always be re-assigned to be the
938   // arguments.
939   initValueArray(MInLocs, 1, 2);
940   initValueArray(MOutLocs, 1, 2);
941   MInLocs[0][0] = ValueIDNum(0, 1, RspLoc);
942   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
943   EXPECT_EQ(MInLocs[0][0], ValueIDNum(0, 0, RspLoc));
944   EXPECT_EQ(MOutLocs[0][0], ValueIDNum(0, 0, RspLoc));
945 
946   // Now insert something into the transfer function to assign to the single
947   // machine location.
948   TransferFunc[0].insert({RspLoc, ValueIDNum(0, 1, RspLoc)});
949   initValueArray(MInLocs, 1, 2);
950   initValueArray(MOutLocs, 1, 2);
951   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
952   EXPECT_EQ(MInLocs[0][0], ValueIDNum(0, 0, RspLoc));
953   EXPECT_EQ(MOutLocs[0][0], ValueIDNum(0, 1, RspLoc));
954   TransferFunc[0].clear();
955 
956   // Add a new register to be tracked, and insert it into the transfer function
957   // as a copy. The output of $rax should be the live-in value of $rsp.
958   Register RAX = getRegByName("RAX");
959   LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX);
960   TransferFunc[0].insert({RspLoc, ValueIDNum(0, 1, RspLoc)});
961   TransferFunc[0].insert({RaxLoc, ValueIDNum(0, 0, RspLoc)});
962   initValueArray(MInLocs, 1, 2);
963   initValueArray(MOutLocs, 1, 2);
964   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
965   EXPECT_EQ(MInLocs[0][0], ValueIDNum(0, 0, RspLoc));
966   EXPECT_EQ(MInLocs[0][1], ValueIDNum(0, 0, RaxLoc));
967   EXPECT_EQ(MOutLocs[0][0], ValueIDNum(0, 1, RspLoc));
968   EXPECT_EQ(MOutLocs[0][1], ValueIDNum(0, 0, RspLoc)); // Rax contains RspLoc.
969   TransferFunc[0].clear();
970 }
971 
972 TEST_F(InstrRefLDVTest, MLocDiamondBlocks) {
973   // Test that information flows from the entry block to two successors.
974   //        entry
975   //        /  \
976   //      br1  br2
977   //        \  /
978   //         ret
979   setupDiamondBlocks();
980 
981   ASSERT_TRUE(MTracker->getNumLocs() == 1);
982   LocIdx RspLoc(0);
983   Register RAX = getRegByName("RAX");
984   LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX);
985 
986   auto [MInLocs, MOutLocs] = allocValueTables(4, 2);
987 
988   // Transfer function: start with nothing.
989   SmallVector<MLocTransferMap, 1> TransferFunc;
990   TransferFunc.resize(4);
991 
992   // Name some values.
993   unsigned EntryBlk = 0, BrBlk1 = 1, BrBlk2 = 2, RetBlk = 3;
994 
995   ValueIDNum LiveInRsp(EntryBlk, 0, RspLoc);
996   ValueIDNum RspDefInBlk0(EntryBlk, 1, RspLoc);
997   ValueIDNum RspDefInBlk1(BrBlk1, 1, RspLoc);
998   ValueIDNum RspDefInBlk2(BrBlk2, 1, RspLoc);
999   ValueIDNum RspPHIInBlk3(RetBlk, 0, RspLoc);
1000   ValueIDNum RaxLiveInBlk1(BrBlk1, 0, RaxLoc);
1001   ValueIDNum RaxLiveInBlk2(BrBlk2, 0, RaxLoc);
1002 
1003   // With no transfer function, the live-in values to the entry block should
1004   // propagate to all live-outs and the live-ins to the two successor blocks.
1005   // IN ADDITION: this checks that the exit block doesn't get a PHI put in it.
1006   initValueArray(MInLocs, 4, 2);
1007   initValueArray(MOutLocs, 4, 2);
1008   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1009   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1010   EXPECT_EQ(MInLocs[1][0], LiveInRsp);
1011   EXPECT_EQ(MInLocs[2][0], LiveInRsp);
1012   EXPECT_EQ(MInLocs[3][0], LiveInRsp);
1013   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1014   EXPECT_EQ(MOutLocs[1][0], LiveInRsp);
1015   EXPECT_EQ(MOutLocs[2][0], LiveInRsp);
1016   EXPECT_EQ(MOutLocs[3][0], LiveInRsp);
1017   // (Skipped writing out locations for $rax).
1018 
1019   // Check that a def of $rsp in the entry block will likewise reach all the
1020   // successors.
1021   TransferFunc[0].insert({RspLoc, RspDefInBlk0});
1022   initValueArray(MInLocs, 4, 2);
1023   initValueArray(MOutLocs, 4, 2);
1024   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1025   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1026   EXPECT_EQ(MInLocs[1][0], RspDefInBlk0);
1027   EXPECT_EQ(MInLocs[2][0], RspDefInBlk0);
1028   EXPECT_EQ(MInLocs[3][0], RspDefInBlk0);
1029   EXPECT_EQ(MOutLocs[0][0], RspDefInBlk0);
1030   EXPECT_EQ(MOutLocs[1][0], RspDefInBlk0);
1031   EXPECT_EQ(MOutLocs[2][0], RspDefInBlk0);
1032   EXPECT_EQ(MOutLocs[3][0], RspDefInBlk0);
1033   TransferFunc[0].clear();
1034 
1035   // Def in one branch of the diamond means that we need a PHI in the ret block
1036   TransferFunc[0].insert({RspLoc, RspDefInBlk0});
1037   TransferFunc[1].insert({RspLoc, RspDefInBlk1});
1038   initValueArray(MInLocs, 4, 2);
1039   initValueArray(MOutLocs, 4, 2);
1040   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1041   // This value map: like above, where RspDefInBlk0 is propagated through one
1042   // branch of the diamond, but is def'ed in the live-outs of the other. The
1043   // ret / merging block should have a PHI in its live-ins.
1044   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1045   EXPECT_EQ(MInLocs[1][0], RspDefInBlk0);
1046   EXPECT_EQ(MInLocs[2][0], RspDefInBlk0);
1047   EXPECT_EQ(MInLocs[3][0], RspPHIInBlk3);
1048   EXPECT_EQ(MOutLocs[0][0], RspDefInBlk0);
1049   EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1);
1050   EXPECT_EQ(MOutLocs[2][0], RspDefInBlk0);
1051   EXPECT_EQ(MOutLocs[3][0], RspPHIInBlk3);
1052   TransferFunc[0].clear();
1053   TransferFunc[1].clear();
1054 
1055   // If we have differeing defs in either side of the diamond, we should
1056   // continue to produce a PHI,
1057   TransferFunc[0].insert({RspLoc, RspDefInBlk0});
1058   TransferFunc[1].insert({RspLoc, RspDefInBlk1});
1059   TransferFunc[2].insert({RspLoc, RspDefInBlk2});
1060   initValueArray(MInLocs, 4, 2);
1061   initValueArray(MOutLocs, 4, 2);
1062   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1063   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1064   EXPECT_EQ(MInLocs[1][0], RspDefInBlk0);
1065   EXPECT_EQ(MInLocs[2][0], RspDefInBlk0);
1066   EXPECT_EQ(MInLocs[3][0], RspPHIInBlk3);
1067   EXPECT_EQ(MOutLocs[0][0], RspDefInBlk0);
1068   EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1);
1069   EXPECT_EQ(MOutLocs[2][0], RspDefInBlk2);
1070   EXPECT_EQ(MOutLocs[3][0], RspPHIInBlk3);
1071   TransferFunc[0].clear();
1072   TransferFunc[1].clear();
1073   TransferFunc[2].clear();
1074 
1075   // If we have defs of the same value on either side of the branch, a PHI will
1076   // initially be created, however value propagation should then eliminate it.
1077   // Encode this by copying the live-in value to $rax, and copying it to $rsp
1078   // from $rax in each branch of the diamond. We don't allow the definition of
1079   // arbitary values in transfer functions.
1080   TransferFunc[0].insert({RspLoc, RspDefInBlk0});
1081   TransferFunc[0].insert({RaxLoc, LiveInRsp});
1082   TransferFunc[1].insert({RspLoc, RaxLiveInBlk1});
1083   TransferFunc[2].insert({RspLoc, RaxLiveInBlk2});
1084   initValueArray(MInLocs, 4, 2);
1085   initValueArray(MOutLocs, 4, 2);
1086   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1087   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1088   EXPECT_EQ(MInLocs[1][0], RspDefInBlk0);
1089   EXPECT_EQ(MInLocs[2][0], RspDefInBlk0);
1090   EXPECT_EQ(MInLocs[3][0], LiveInRsp);
1091   EXPECT_EQ(MOutLocs[0][0], RspDefInBlk0);
1092   EXPECT_EQ(MOutLocs[1][0], LiveInRsp);
1093   EXPECT_EQ(MOutLocs[2][0], LiveInRsp);
1094   EXPECT_EQ(MOutLocs[3][0], LiveInRsp);
1095   TransferFunc[0].clear();
1096   TransferFunc[1].clear();
1097   TransferFunc[2].clear();
1098 }
1099 
1100 TEST_F(InstrRefLDVTest, MLocDiamondSpills) {
1101   // Test that defs in stack locations that require PHIs, cause PHIs to be
1102   // installed in aliasing locations. i.e., if there's a PHI in the lower
1103   // 8 bits of the stack, there should be PHIs for 16/32/64 bit locations
1104   // on the stack too.
1105   // Technically this isn't needed for accuracy: we should calculate PHIs
1106   // independently for each location. However, because there's an optimisation
1107   // that only places PHIs for the lower "interfering" parts of stack slots,
1108   // test for this behaviour.
1109   setupDiamondBlocks();
1110 
1111   ASSERT_TRUE(MTracker->getNumLocs() == 1);
1112   LocIdx RspLoc(0);
1113 
1114   // Create a stack location and ensure it's tracked.
1115   SpillLoc SL = {getRegByName("RSP"), StackOffset::getFixed(-8)};
1116   SpillLocationNo SpillNo = *MTracker->getOrTrackSpillLoc(SL);
1117   ASSERT_EQ(MTracker->getNumLocs(), 11u); // Tracks all possible stack locs.
1118   // Locations are: RSP, stack slots from 2^3 bits wide up to 2^9 for zmm regs,
1119   // then slots for sub_8bit_hi and sub_16bit_hi ({8, 8} and {16, 16}).
1120   // Finally, one for spilt fp80 registers.
1121 
1122   // Pick out the locations on the stack that various x86 regs would be written
1123   // to. HAX is the upper 16 bits of EAX.
1124   unsigned ALID = MTracker->getLocID(SpillNo, {8, 0});
1125   unsigned AHID = MTracker->getLocID(SpillNo, {8, 8});
1126   unsigned AXID = MTracker->getLocID(SpillNo, {16, 0});
1127   unsigned EAXID = MTracker->getLocID(SpillNo, {32, 0});
1128   unsigned HAXID = MTracker->getLocID(SpillNo, {16, 16});
1129   unsigned RAXID = MTracker->getLocID(SpillNo, {64, 0});
1130   LocIdx ALStackLoc = MTracker->getSpillMLoc(ALID);
1131   LocIdx AHStackLoc = MTracker->getSpillMLoc(AHID);
1132   LocIdx AXStackLoc = MTracker->getSpillMLoc(AXID);
1133   LocIdx EAXStackLoc = MTracker->getSpillMLoc(EAXID);
1134   LocIdx HAXStackLoc = MTracker->getSpillMLoc(HAXID);
1135   LocIdx RAXStackLoc = MTracker->getSpillMLoc(RAXID);
1136   // There are other locations, for things like xmm0, which we're going to
1137   // ignore here.
1138 
1139   auto [MInLocs, MOutLocs] = allocValueTables(4, 11);
1140 
1141   // Transfer function: start with nothing.
1142   SmallVector<MLocTransferMap, 1> TransferFunc;
1143   TransferFunc.resize(4);
1144 
1145   // Name some values.
1146   unsigned EntryBlk = 0, Blk1 = 1, RetBlk = 3;
1147 
1148   ValueIDNum LiveInRsp(EntryBlk, 0, RspLoc);
1149   ValueIDNum ALLiveIn(EntryBlk, 0, ALStackLoc);
1150   ValueIDNum AHLiveIn(EntryBlk, 0, AHStackLoc);
1151   ValueIDNum HAXLiveIn(EntryBlk, 0, HAXStackLoc);
1152   ValueIDNum ALPHI(RetBlk, 0, ALStackLoc);
1153   ValueIDNum AXPHI(RetBlk, 0, AXStackLoc);
1154   ValueIDNum EAXPHI(RetBlk, 0, EAXStackLoc);
1155   ValueIDNum HAXPHI(RetBlk, 0, HAXStackLoc);
1156   ValueIDNum RAXPHI(RetBlk, 0, RAXStackLoc);
1157 
1158   ValueIDNum ALDefInBlk1(Blk1, 1, ALStackLoc);
1159   ValueIDNum HAXDefInBlk1(Blk1, 1, HAXStackLoc);
1160 
1161   SmallPtrSet<MachineBasicBlock *, 4> AllBlocks{MBB0, MBB1, MBB2, MBB3};
1162 
1163   // If we put defs into one side of the diamond, for AL and HAX, then we should
1164   // find all aliasing positions have PHIs placed. This isn't technically what
1165   // the transfer function says to do: but we're testing that the optimisation
1166   // to reduce IDF calculation does the right thing.
1167   // AH should not be def'd: it don't alias AL or HAX.
1168   //
1169   // NB: we don't call buildMLocValueMap, because it will try to eliminate the
1170   // upper-slot PHIs, and succeed because of our slightly cooked transfer
1171   // function.
1172   TransferFunc[1].insert({ALStackLoc, ALDefInBlk1});
1173   TransferFunc[1].insert({HAXStackLoc, HAXDefInBlk1});
1174   initValueArray(MInLocs, 4, 11);
1175   placeMLocPHIs(*MF, AllBlocks, MInLocs, TransferFunc);
1176   EXPECT_EQ(MInLocs[3][ALStackLoc.asU64()], ALPHI);
1177   EXPECT_EQ(MInLocs[3][AXStackLoc.asU64()], AXPHI);
1178   EXPECT_EQ(MInLocs[3][EAXStackLoc.asU64()], EAXPHI);
1179   EXPECT_EQ(MInLocs[3][HAXStackLoc.asU64()], HAXPHI);
1180   EXPECT_EQ(MInLocs[3][RAXStackLoc.asU64()], RAXPHI);
1181   // AH should be left untouched,
1182   EXPECT_EQ(MInLocs[3][AHStackLoc.asU64()], ValueIDNum::EmptyValue);
1183 }
1184 
1185 TEST_F(InstrRefLDVTest, MLocSimpleLoop) {
1186   //    entry
1187   //     |
1188   //     |/-----\
1189   //    loopblk |
1190   //     |\-----/
1191   //     |
1192   //     ret
1193   setupSimpleLoop();
1194 
1195   ASSERT_TRUE(MTracker->getNumLocs() == 1);
1196   LocIdx RspLoc(0);
1197   Register RAX = getRegByName("RAX");
1198   LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX);
1199 
1200   auto [MInLocs, MOutLocs] = allocValueTables(3, 2);
1201 
1202   SmallVector<MLocTransferMap, 1> TransferFunc;
1203   TransferFunc.resize(3);
1204 
1205   // Name some values.
1206   unsigned EntryBlk = 0, LoopBlk = 1, RetBlk = 2;
1207 
1208   ValueIDNum LiveInRsp(EntryBlk, 0, RspLoc);
1209   ValueIDNum RspPHIInBlk1(LoopBlk, 0, RspLoc);
1210   ValueIDNum RspDefInBlk1(LoopBlk, 1, RspLoc);
1211   ValueIDNum LiveInRax(EntryBlk, 0, RaxLoc);
1212   ValueIDNum RaxPHIInBlk1(LoopBlk, 0, RaxLoc);
1213   ValueIDNum RaxPHIInBlk2(RetBlk, 0, RaxLoc);
1214 
1215   // Begin test with all locations being live-through.
1216   initValueArray(MInLocs, 3, 2);
1217   initValueArray(MOutLocs, 3, 2);
1218   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1219   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1220   EXPECT_EQ(MInLocs[1][0], LiveInRsp);
1221   EXPECT_EQ(MInLocs[2][0], LiveInRsp);
1222   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1223   EXPECT_EQ(MOutLocs[1][0], LiveInRsp);
1224   EXPECT_EQ(MOutLocs[2][0], LiveInRsp);
1225 
1226   // Add a def of $rsp to the loop block: it should be in the live-outs, but
1227   // should cause a PHI to be placed in the live-ins. Test the transfer function
1228   // by copying that PHI into $rax in the loop, then back to $rsp in the ret
1229   // block.
1230   TransferFunc[1].insert({RspLoc, RspDefInBlk1});
1231   TransferFunc[1].insert({RaxLoc, RspPHIInBlk1});
1232   TransferFunc[2].insert({RspLoc, RaxPHIInBlk2});
1233   initValueArray(MInLocs, 3, 2);
1234   initValueArray(MOutLocs, 3, 2);
1235   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1236   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1237   EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1);
1238   EXPECT_EQ(MInLocs[2][0], RspDefInBlk1);
1239   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1240   EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1);
1241   EXPECT_EQ(MOutLocs[2][0], RspPHIInBlk1);
1242   // Check rax as well,
1243   EXPECT_EQ(MInLocs[0][1], LiveInRax);
1244   EXPECT_EQ(MInLocs[1][1], RaxPHIInBlk1);
1245   EXPECT_EQ(MInLocs[2][1], RspPHIInBlk1);
1246   EXPECT_EQ(MOutLocs[0][1], LiveInRax);
1247   EXPECT_EQ(MOutLocs[1][1], RspPHIInBlk1);
1248   EXPECT_EQ(MOutLocs[2][1], RspPHIInBlk1);
1249   TransferFunc[1].clear();
1250   TransferFunc[2].clear();
1251 
1252   // As with the diamond case, a PHI will be created if there's a (implicit)
1253   // def in the entry block and loop block; but should be value propagated away
1254   // if it copies in the same value. Copy live-in $rsp to $rax, then copy it
1255   // into $rsp in the loop. Encoded as copying the live-in $rax value in block 1
1256   // to $rsp.
1257   TransferFunc[0].insert({RaxLoc, LiveInRsp});
1258   TransferFunc[1].insert({RspLoc, RaxPHIInBlk1});
1259   initValueArray(MInLocs, 3, 2);
1260   initValueArray(MOutLocs, 3, 2);
1261   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1262   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1263   EXPECT_EQ(MInLocs[1][0], LiveInRsp);
1264   EXPECT_EQ(MInLocs[2][0], LiveInRsp);
1265   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1266   EXPECT_EQ(MOutLocs[1][0], LiveInRsp);
1267   EXPECT_EQ(MOutLocs[2][0], LiveInRsp);
1268   // Check $rax's values.
1269   EXPECT_EQ(MInLocs[0][1], LiveInRax);
1270   EXPECT_EQ(MInLocs[1][1], LiveInRsp);
1271   EXPECT_EQ(MInLocs[2][1], LiveInRsp);
1272   EXPECT_EQ(MOutLocs[0][1], LiveInRsp);
1273   EXPECT_EQ(MOutLocs[1][1], LiveInRsp);
1274   EXPECT_EQ(MOutLocs[2][1], LiveInRsp);
1275   TransferFunc[0].clear();
1276   TransferFunc[1].clear();
1277 }
1278 
1279 TEST_F(InstrRefLDVTest, MLocNestedLoop) {
1280   //    entry
1281   //     |
1282   //    loop1
1283   //     ^\
1284   //     | \    /-\
1285   //     |  loop2  |
1286   //     |  /   \-/
1287   //     ^ /
1288   //     join
1289   //     |
1290   //     ret
1291   setupNestedLoops();
1292 
1293   ASSERT_TRUE(MTracker->getNumLocs() == 1);
1294   LocIdx RspLoc(0);
1295   Register RAX = getRegByName("RAX");
1296   LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX);
1297 
1298   auto [MInLocs, MOutLocs] = allocValueTables(5, 2);
1299 
1300   SmallVector<MLocTransferMap, 1> TransferFunc;
1301   TransferFunc.resize(5);
1302 
1303   unsigned EntryBlk = 0, Loop1Blk = 1, Loop2Blk = 2, JoinBlk = 3;
1304 
1305   ValueIDNum LiveInRsp(EntryBlk, 0, RspLoc);
1306   ValueIDNum RspPHIInBlk1(Loop1Blk, 0, RspLoc);
1307   ValueIDNum RspDefInBlk1(Loop1Blk, 1, RspLoc);
1308   ValueIDNum RspPHIInBlk2(Loop2Blk, 0, RspLoc);
1309   ValueIDNum RspDefInBlk2(Loop2Blk, 1, RspLoc);
1310   ValueIDNum RspDefInBlk3(JoinBlk, 1, RspLoc);
1311   ValueIDNum LiveInRax(EntryBlk, 0, RaxLoc);
1312   ValueIDNum RaxPHIInBlk1(Loop1Blk, 0, RaxLoc);
1313   ValueIDNum RaxPHIInBlk2(Loop2Blk, 0, RaxLoc);
1314 
1315   // Like the other tests: first ensure that if there's nothing in the transfer
1316   // function, then everything is live-through (check $rsp).
1317   initValueArray(MInLocs, 5, 2);
1318   initValueArray(MOutLocs, 5, 2);
1319   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1320   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1321   EXPECT_EQ(MInLocs[1][0], LiveInRsp);
1322   EXPECT_EQ(MInLocs[2][0], LiveInRsp);
1323   EXPECT_EQ(MInLocs[3][0], LiveInRsp);
1324   EXPECT_EQ(MInLocs[4][0], LiveInRsp);
1325   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1326   EXPECT_EQ(MOutLocs[1][0], LiveInRsp);
1327   EXPECT_EQ(MOutLocs[2][0], LiveInRsp);
1328   EXPECT_EQ(MOutLocs[3][0], LiveInRsp);
1329   EXPECT_EQ(MOutLocs[4][0], LiveInRsp);
1330 
1331   // A def in the inner loop means we should get PHIs at the heads of both
1332   // loops. Live-outs of the last three blocks will be the def, as it dominates
1333   // those.
1334   TransferFunc[2].insert({RspLoc, RspDefInBlk2});
1335   initValueArray(MInLocs, 5, 2);
1336   initValueArray(MOutLocs, 5, 2);
1337   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1338   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1339   EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1);
1340   EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2);
1341   EXPECT_EQ(MInLocs[3][0], RspDefInBlk2);
1342   EXPECT_EQ(MInLocs[4][0], RspDefInBlk2);
1343   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1344   EXPECT_EQ(MOutLocs[1][0], RspPHIInBlk1);
1345   EXPECT_EQ(MOutLocs[2][0], RspDefInBlk2);
1346   EXPECT_EQ(MOutLocs[3][0], RspDefInBlk2);
1347   EXPECT_EQ(MOutLocs[4][0], RspDefInBlk2);
1348   TransferFunc[2].clear();
1349 
1350   // Adding a def to the outer loop header shouldn't affect this much -- the
1351   // live-out of block 1 changes.
1352   TransferFunc[1].insert({RspLoc, RspDefInBlk1});
1353   TransferFunc[2].insert({RspLoc, RspDefInBlk2});
1354   initValueArray(MInLocs, 5, 2);
1355   initValueArray(MOutLocs, 5, 2);
1356   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1357   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1358   EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1);
1359   EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2);
1360   EXPECT_EQ(MInLocs[3][0], RspDefInBlk2);
1361   EXPECT_EQ(MInLocs[4][0], RspDefInBlk2);
1362   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1363   EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1);
1364   EXPECT_EQ(MOutLocs[2][0], RspDefInBlk2);
1365   EXPECT_EQ(MOutLocs[3][0], RspDefInBlk2);
1366   EXPECT_EQ(MOutLocs[4][0], RspDefInBlk2);
1367   TransferFunc[1].clear();
1368   TransferFunc[2].clear();
1369 
1370   // Likewise, putting a def in the outer loop tail shouldn't affect where
1371   // the PHIs go, and should propagate into the ret block.
1372 
1373   TransferFunc[1].insert({RspLoc, RspDefInBlk1});
1374   TransferFunc[2].insert({RspLoc, RspDefInBlk2});
1375   TransferFunc[3].insert({RspLoc, RspDefInBlk3});
1376   initValueArray(MInLocs, 5, 2);
1377   initValueArray(MOutLocs, 5, 2);
1378   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1379   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1380   EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1);
1381   EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2);
1382   EXPECT_EQ(MInLocs[3][0], RspDefInBlk2);
1383   EXPECT_EQ(MInLocs[4][0], RspDefInBlk3);
1384   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1385   EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1);
1386   EXPECT_EQ(MOutLocs[2][0], RspDefInBlk2);
1387   EXPECT_EQ(MOutLocs[3][0], RspDefInBlk3);
1388   EXPECT_EQ(MOutLocs[4][0], RspDefInBlk3);
1389   TransferFunc[1].clear();
1390   TransferFunc[2].clear();
1391   TransferFunc[3].clear();
1392 
1393   // However: if we don't def in the inner-loop, then we just have defs in the
1394   // head and tail of the outer loop. The inner loop should be live-through.
1395   TransferFunc[1].insert({RspLoc, RspDefInBlk1});
1396   TransferFunc[3].insert({RspLoc, RspDefInBlk3});
1397   initValueArray(MInLocs, 5, 2);
1398   initValueArray(MOutLocs, 5, 2);
1399   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1400   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1401   EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1);
1402   EXPECT_EQ(MInLocs[2][0], RspDefInBlk1);
1403   EXPECT_EQ(MInLocs[3][0], RspDefInBlk1);
1404   EXPECT_EQ(MInLocs[4][0], RspDefInBlk3);
1405   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1406   EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1);
1407   EXPECT_EQ(MOutLocs[2][0], RspDefInBlk1);
1408   EXPECT_EQ(MOutLocs[3][0], RspDefInBlk3);
1409   EXPECT_EQ(MOutLocs[4][0], RspDefInBlk3);
1410   TransferFunc[1].clear();
1411   TransferFunc[3].clear();
1412 
1413   // Check that this still works if we copy RspDefInBlk1 to $rax and then
1414   // copy it back into $rsp in the inner loop.
1415   TransferFunc[1].insert({RspLoc, RspDefInBlk1});
1416   TransferFunc[1].insert({RaxLoc, RspDefInBlk1});
1417   TransferFunc[2].insert({RspLoc, RaxPHIInBlk2});
1418   TransferFunc[3].insert({RspLoc, RspDefInBlk3});
1419   initValueArray(MInLocs, 5, 2);
1420   initValueArray(MOutLocs, 5, 2);
1421   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1422   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1423   EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1);
1424   EXPECT_EQ(MInLocs[2][0], RspDefInBlk1);
1425   EXPECT_EQ(MInLocs[3][0], RspDefInBlk1);
1426   EXPECT_EQ(MInLocs[4][0], RspDefInBlk3);
1427   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1428   EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1);
1429   EXPECT_EQ(MOutLocs[2][0], RspDefInBlk1);
1430   EXPECT_EQ(MOutLocs[3][0], RspDefInBlk3);
1431   EXPECT_EQ(MOutLocs[4][0], RspDefInBlk3);
1432   // Look at raxes value in the relevant blocks,
1433   EXPECT_EQ(MInLocs[2][1], RspDefInBlk1);
1434   EXPECT_EQ(MOutLocs[1][1], RspDefInBlk1);
1435   TransferFunc[1].clear();
1436   TransferFunc[2].clear();
1437   TransferFunc[3].clear();
1438 
1439   // If we have a single def in the tail of the outer loop, that should produce
1440   // a PHI at the loop head, and be live-through the inner loop.
1441   TransferFunc[3].insert({RspLoc, RspDefInBlk3});
1442   initValueArray(MInLocs, 5, 2);
1443   initValueArray(MOutLocs, 5, 2);
1444   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1445   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1446   EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1);
1447   EXPECT_EQ(MInLocs[2][0], RspPHIInBlk1);
1448   EXPECT_EQ(MInLocs[3][0], RspPHIInBlk1);
1449   EXPECT_EQ(MInLocs[4][0], RspDefInBlk3);
1450   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1451   EXPECT_EQ(MOutLocs[1][0], RspPHIInBlk1);
1452   EXPECT_EQ(MOutLocs[2][0], RspPHIInBlk1);
1453   EXPECT_EQ(MOutLocs[3][0], RspDefInBlk3);
1454   EXPECT_EQ(MOutLocs[4][0], RspDefInBlk3);
1455   TransferFunc[3].clear();
1456 
1457   // And if we copy from $rsp to $rax in block 2, it should resolve to the PHI
1458   // in block 1, and we should keep that value in rax until the ret block.
1459   // There'll be a PHI in block 1 and 2, because we're putting a def in the
1460   // inner loop.
1461   TransferFunc[2].insert({RaxLoc, RspPHIInBlk2});
1462   TransferFunc[3].insert({RspLoc, RspDefInBlk3});
1463   initValueArray(MInLocs, 5, 2);
1464   initValueArray(MOutLocs, 5, 2);
1465   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1466   // Examining the values of rax,
1467   EXPECT_EQ(MInLocs[0][1], LiveInRax);
1468   EXPECT_EQ(MInLocs[1][1], RaxPHIInBlk1);
1469   EXPECT_EQ(MInLocs[2][1], RaxPHIInBlk2);
1470   EXPECT_EQ(MInLocs[3][1], RspPHIInBlk1);
1471   EXPECT_EQ(MInLocs[4][1], RspPHIInBlk1);
1472   EXPECT_EQ(MOutLocs[0][1], LiveInRax);
1473   EXPECT_EQ(MOutLocs[1][1], RaxPHIInBlk1);
1474   EXPECT_EQ(MOutLocs[2][1], RspPHIInBlk1);
1475   EXPECT_EQ(MOutLocs[3][1], RspPHIInBlk1);
1476   EXPECT_EQ(MOutLocs[4][1], RspPHIInBlk1);
1477   TransferFunc[2].clear();
1478   TransferFunc[3].clear();
1479 }
1480 
1481 TEST_F(InstrRefLDVTest, MLocNoDominatingLoop) {
1482   //           entry
1483   //            / \
1484   //           /   \
1485   //          /     \
1486   //        head1   head2
1487   //        ^  \   /   ^
1488   //        ^   \ /    ^
1489   //        \-joinblk -/
1490   //             |
1491   //            ret
1492   setupNoDominatingLoop();
1493 
1494   ASSERT_TRUE(MTracker->getNumLocs() == 1);
1495   LocIdx RspLoc(0);
1496   Register RAX = getRegByName("RAX");
1497   LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX);
1498 
1499   auto [MInLocs, MOutLocs] = allocValueTables(5, 2);
1500 
1501   SmallVector<MLocTransferMap, 1> TransferFunc;
1502   TransferFunc.resize(5);
1503 
1504   unsigned EntryBlk = 0, Head1Blk = 1, Head2Blk = 2, JoinBlk = 3;
1505 
1506   ValueIDNum LiveInRsp(EntryBlk, 0, RspLoc);
1507   ValueIDNum RspPHIInBlk1(Head1Blk, 0, RspLoc);
1508   ValueIDNum RspDefInBlk1(Head1Blk, 1, RspLoc);
1509   ValueIDNum RspPHIInBlk2(Head2Blk, 0, RspLoc);
1510   ValueIDNum RspDefInBlk2(Head2Blk, 1, RspLoc);
1511   ValueIDNum RspPHIInBlk3(JoinBlk, 0, RspLoc);
1512   ValueIDNum RspDefInBlk3(JoinBlk, 1, RspLoc);
1513   ValueIDNum RaxPHIInBlk1(Head1Blk, 0, RaxLoc);
1514   ValueIDNum RaxPHIInBlk2(Head2Blk, 0, RaxLoc);
1515 
1516   // As ever, test that everything is live-through if there are no defs.
1517   initValueArray(MInLocs, 5, 2);
1518   initValueArray(MOutLocs, 5, 2);
1519   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1520   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1521   EXPECT_EQ(MInLocs[1][0], LiveInRsp);
1522   EXPECT_EQ(MInLocs[2][0], LiveInRsp);
1523   EXPECT_EQ(MInLocs[3][0], LiveInRsp);
1524   EXPECT_EQ(MInLocs[4][0], LiveInRsp);
1525   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1526   EXPECT_EQ(MOutLocs[1][0], LiveInRsp);
1527   EXPECT_EQ(MOutLocs[2][0], LiveInRsp);
1528   EXPECT_EQ(MOutLocs[3][0], LiveInRsp);
1529   EXPECT_EQ(MOutLocs[4][0], LiveInRsp);
1530 
1531   // Putting a def in the 'join' block will cause us to have two distinct
1532   // PHIs in each loop head, then on entry to the join block.
1533   TransferFunc[3].insert({RspLoc, RspDefInBlk3});
1534   initValueArray(MInLocs, 5, 2);
1535   initValueArray(MOutLocs, 5, 2);
1536   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1537   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1538   EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1);
1539   EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2);
1540   EXPECT_EQ(MInLocs[3][0], RspPHIInBlk3);
1541   EXPECT_EQ(MInLocs[4][0], RspDefInBlk3);
1542   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1543   EXPECT_EQ(MOutLocs[1][0], RspPHIInBlk1);
1544   EXPECT_EQ(MOutLocs[2][0], RspPHIInBlk2);
1545   EXPECT_EQ(MOutLocs[3][0], RspDefInBlk3);
1546   EXPECT_EQ(MOutLocs[4][0], RspDefInBlk3);
1547   TransferFunc[3].clear();
1548 
1549   // We should get the same behaviour if we put the def in either of the
1550   // loop heads -- it should force the other head to be a PHI.
1551   TransferFunc[1].insert({RspLoc, RspDefInBlk1});
1552   initValueArray(MInLocs, 5, 2);
1553   initValueArray(MOutLocs, 5, 2);
1554   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1555   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1556   EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1);
1557   EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2);
1558   EXPECT_EQ(MInLocs[3][0], RspPHIInBlk3);
1559   EXPECT_EQ(MInLocs[4][0], RspPHIInBlk3);
1560   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1561   EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1);
1562   EXPECT_EQ(MOutLocs[2][0], RspPHIInBlk2);
1563   EXPECT_EQ(MOutLocs[3][0], RspPHIInBlk3);
1564   EXPECT_EQ(MOutLocs[4][0], RspPHIInBlk3);
1565   TransferFunc[1].clear();
1566 
1567   // Check symmetry,
1568   TransferFunc[2].insert({RspLoc, RspDefInBlk2});
1569   initValueArray(MInLocs, 5, 2);
1570   initValueArray(MOutLocs, 5, 2);
1571   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1572   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1573   EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1);
1574   EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2);
1575   EXPECT_EQ(MInLocs[3][0], RspPHIInBlk3);
1576   EXPECT_EQ(MInLocs[4][0], RspPHIInBlk3);
1577   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1578   EXPECT_EQ(MOutLocs[1][0], RspPHIInBlk1);
1579   EXPECT_EQ(MOutLocs[2][0], RspDefInBlk2);
1580   EXPECT_EQ(MOutLocs[3][0], RspPHIInBlk3);
1581   EXPECT_EQ(MOutLocs[4][0], RspPHIInBlk3);
1582   TransferFunc[2].clear();
1583 
1584   // Test some scenarios where there _shouldn't_ be any PHIs created at heads.
1585   // These are those PHIs are created, but value propagation eliminates them.
1586   // For example, lets copy rsp-livein to $rsp inside each loop head, so that
1587   // there's no need for a PHI in the join block. Put a def of $rsp in block 3
1588   // to force PHIs elsewhere.
1589   TransferFunc[0].insert({RaxLoc, LiveInRsp});
1590   TransferFunc[1].insert({RspLoc, RaxPHIInBlk1});
1591   TransferFunc[2].insert({RspLoc, RaxPHIInBlk2});
1592   TransferFunc[3].insert({RspLoc, RspDefInBlk3});
1593   initValueArray(MInLocs, 5, 2);
1594   initValueArray(MOutLocs, 5, 2);
1595   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1596   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1597   EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1);
1598   EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2);
1599   EXPECT_EQ(MInLocs[3][0], LiveInRsp);
1600   EXPECT_EQ(MInLocs[4][0], RspDefInBlk3);
1601   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1602   EXPECT_EQ(MOutLocs[1][0], LiveInRsp);
1603   EXPECT_EQ(MOutLocs[2][0], LiveInRsp);
1604   EXPECT_EQ(MOutLocs[3][0], RspDefInBlk3);
1605   EXPECT_EQ(MOutLocs[4][0], RspDefInBlk3);
1606   TransferFunc[0].clear();
1607   TransferFunc[1].clear();
1608   TransferFunc[2].clear();
1609   TransferFunc[3].clear();
1610 
1611   // In fact, if we eliminate the def in block 3, none of those PHIs are
1612   // necessary, as we're just repeatedly copying LiveInRsp into $rsp. They
1613   // should all be value propagated out.
1614   TransferFunc[0].insert({RaxLoc, LiveInRsp});
1615   TransferFunc[1].insert({RspLoc, RaxPHIInBlk1});
1616   TransferFunc[2].insert({RspLoc, RaxPHIInBlk2});
1617   initValueArray(MInLocs, 5, 2);
1618   initValueArray(MOutLocs, 5, 2);
1619   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1620   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1621   EXPECT_EQ(MInLocs[1][0], LiveInRsp);
1622   EXPECT_EQ(MInLocs[2][0], LiveInRsp);
1623   EXPECT_EQ(MInLocs[3][0], LiveInRsp);
1624   EXPECT_EQ(MInLocs[4][0], LiveInRsp);
1625   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1626   EXPECT_EQ(MOutLocs[1][0], LiveInRsp);
1627   EXPECT_EQ(MOutLocs[2][0], LiveInRsp);
1628   EXPECT_EQ(MOutLocs[3][0], LiveInRsp);
1629   EXPECT_EQ(MOutLocs[4][0], LiveInRsp);
1630   TransferFunc[0].clear();
1631   TransferFunc[1].clear();
1632   TransferFunc[2].clear();
1633 }
1634 
1635 TEST_F(InstrRefLDVTest, MLocBadlyNestedLoops) {
1636   //           entry
1637   //             |
1638   //           loop1 -o
1639   //             | ^
1640   //             | ^
1641   //           loop2 -o
1642   //             | ^
1643   //             | ^
1644   //           loop3 -o
1645   //             |
1646   //            ret
1647   setupBadlyNestedLoops();
1648 
1649   ASSERT_TRUE(MTracker->getNumLocs() == 1);
1650   LocIdx RspLoc(0);
1651   Register RAX = getRegByName("RAX");
1652   LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX);
1653 
1654   auto [MInLocs, MOutLocs] = allocValueTables(5, 2);
1655 
1656   SmallVector<MLocTransferMap, 1> TransferFunc;
1657   TransferFunc.resize(5);
1658 
1659   unsigned EntryBlk = 0, Loop1Blk = 1, Loop2Blk = 2, Loop3Blk = 3;
1660 
1661   ValueIDNum LiveInRsp(EntryBlk, 0, RspLoc);
1662   ValueIDNum RspPHIInBlk1(Loop1Blk, 0, RspLoc);
1663   ValueIDNum RspDefInBlk1(Loop1Blk, 1, RspLoc);
1664   ValueIDNum RspPHIInBlk2(Loop2Blk, 0, RspLoc);
1665   ValueIDNum RspPHIInBlk3(Loop3Blk, 0, RspLoc);
1666   ValueIDNum RspDefInBlk3(Loop3Blk, 1, RspLoc);
1667   ValueIDNum LiveInRax(EntryBlk, 0, RaxLoc);
1668   ValueIDNum RaxPHIInBlk3(Loop3Blk, 0, RaxLoc);
1669 
1670   // As ever, test that everything is live-through if there are no defs.
1671   initValueArray(MInLocs, 5, 2);
1672   initValueArray(MOutLocs, 5, 2);
1673   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1674   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1675   EXPECT_EQ(MInLocs[1][0], LiveInRsp);
1676   EXPECT_EQ(MInLocs[2][0], LiveInRsp);
1677   EXPECT_EQ(MInLocs[3][0], LiveInRsp);
1678   EXPECT_EQ(MInLocs[4][0], LiveInRsp);
1679   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1680   EXPECT_EQ(MOutLocs[1][0], LiveInRsp);
1681   EXPECT_EQ(MOutLocs[2][0], LiveInRsp);
1682   EXPECT_EQ(MOutLocs[3][0], LiveInRsp);
1683   EXPECT_EQ(MOutLocs[4][0], LiveInRsp);
1684 
1685   // A def in loop3 should cause PHIs in every loop block: they're all
1686   // reachable from each other.
1687   TransferFunc[3].insert({RspLoc, RspDefInBlk3});
1688   initValueArray(MInLocs, 5, 2);
1689   initValueArray(MOutLocs, 5, 2);
1690   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1691   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1692   EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1);
1693   EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2);
1694   EXPECT_EQ(MInLocs[3][0], RspPHIInBlk3);
1695   EXPECT_EQ(MInLocs[4][0], RspDefInBlk3);
1696   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1697   EXPECT_EQ(MOutLocs[1][0], RspPHIInBlk1);
1698   EXPECT_EQ(MOutLocs[2][0], RspPHIInBlk2);
1699   EXPECT_EQ(MOutLocs[3][0], RspDefInBlk3);
1700   EXPECT_EQ(MOutLocs[4][0], RspDefInBlk3);
1701   TransferFunc[3].clear();
1702 
1703   // A def in loop1 should cause a PHI in loop1, but not the other blocks.
1704   // loop2 and loop3 are dominated by the def in loop1, so they should have
1705   // that value live-through.
1706   TransferFunc[1].insert({RspLoc, RspDefInBlk1});
1707   initValueArray(MInLocs, 5, 2);
1708   initValueArray(MOutLocs, 5, 2);
1709   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1710   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1711   EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1);
1712   EXPECT_EQ(MInLocs[2][0], RspDefInBlk1);
1713   EXPECT_EQ(MInLocs[3][0], RspDefInBlk1);
1714   EXPECT_EQ(MInLocs[4][0], RspDefInBlk1);
1715   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1716   EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1);
1717   EXPECT_EQ(MOutLocs[2][0], RspDefInBlk1);
1718   EXPECT_EQ(MOutLocs[3][0], RspDefInBlk1);
1719   EXPECT_EQ(MOutLocs[4][0], RspDefInBlk1);
1720   TransferFunc[1].clear();
1721 
1722   // As with earlier tricks: copy $rsp to $rax in the entry block, then $rax
1723   // to $rsp in block 3. The only def of $rsp is simply copying the same value
1724   // back into itself, and the value of $rsp is LiveInRsp all the way through.
1725   // PHIs should be created, then value-propagated away...  however this
1726   // doesn't work in practice.
1727   // Consider the entry to loop3: we can determine that there's an incoming
1728   // PHI value from loop2, and LiveInRsp from the self-loop. This would still
1729   // justify having a PHI on entry to loop3. The only way to completely
1730   // value-propagate these PHIs away would be to speculatively explore what
1731   // PHIs could be eliminated and what that would lead to; which is
1732   // combinatorially complex.
1733   // Happily:
1734   //  a) In this scenario, we always have a tracked location for LiveInRsp
1735   //     anyway, so there's no loss in availability,
1736   //  b) Only DBG_PHIs of a register would be vunlerable to this scenario, and
1737   //     even then only if a true PHI became a DBG_PHI and was then optimised
1738   //     through branch folding to no longer be at a CFG join,
1739   //  c) The register allocator can spot this kind of redundant COPY easily,
1740   //     and eliminate it.
1741   //
1742   // This unit test left in as a reference for the limitations of this
1743   // approach. PHIs will be left in $rsp on entry to each block.
1744   TransferFunc[0].insert({RaxLoc, LiveInRsp});
1745   TransferFunc[3].insert({RspLoc, RaxPHIInBlk3});
1746   initValueArray(MInLocs, 5, 2);
1747   initValueArray(MOutLocs, 5, 2);
1748   buildMLocValueMap(MInLocs, MOutLocs, TransferFunc);
1749   EXPECT_EQ(MInLocs[0][0], LiveInRsp);
1750   EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1);
1751   EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2);
1752   EXPECT_EQ(MInLocs[3][0], RspPHIInBlk3);
1753   EXPECT_EQ(MInLocs[4][0], LiveInRsp);
1754   EXPECT_EQ(MOutLocs[0][0], LiveInRsp);
1755   EXPECT_EQ(MOutLocs[1][0], RspPHIInBlk1);
1756   EXPECT_EQ(MOutLocs[2][0], RspPHIInBlk2);
1757   EXPECT_EQ(MOutLocs[3][0], LiveInRsp);
1758   EXPECT_EQ(MOutLocs[4][0], LiveInRsp);
1759   // Check $rax's value. It should have $rsps value from the entry block
1760   // onwards.
1761   EXPECT_EQ(MInLocs[0][1], LiveInRax);
1762   EXPECT_EQ(MInLocs[1][1], LiveInRsp);
1763   EXPECT_EQ(MInLocs[2][1], LiveInRsp);
1764   EXPECT_EQ(MInLocs[3][1], LiveInRsp);
1765   EXPECT_EQ(MInLocs[4][1], LiveInRsp);
1766   EXPECT_EQ(MOutLocs[0][1], LiveInRsp);
1767   EXPECT_EQ(MOutLocs[1][1], LiveInRsp);
1768   EXPECT_EQ(MOutLocs[2][1], LiveInRsp);
1769   EXPECT_EQ(MOutLocs[3][1], LiveInRsp);
1770   EXPECT_EQ(MOutLocs[4][1], LiveInRsp);
1771 }
1772 
1773 TEST_F(InstrRefLDVTest, pickVPHILocDiamond) {
1774   //        entry
1775   //        /  \
1776   //      br1  br2
1777   //        \  /
1778   //         ret
1779   setupDiamondBlocks();
1780 
1781   ASSERT_TRUE(MTracker->getNumLocs() == 1);
1782   LocIdx RspLoc(0);
1783   Register RAX = getRegByName("RAX");
1784   LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX);
1785 
1786   auto [MInLocs, MOutLocs] = allocValueTables(4, 2);
1787 
1788   initValueArray(MOutLocs, 4, 2);
1789 
1790   unsigned EntryBlk = 0, Br2Blk = 2, RetBlk = 3;
1791 
1792   ValueIDNum LiveInRsp(EntryBlk, 0, RspLoc);
1793   ValueIDNum LiveInRax(EntryBlk, 0, RaxLoc);
1794   ValueIDNum RspPHIInBlk2(Br2Blk, 0, RspLoc);
1795   ValueIDNum RspPHIInBlk3(RetBlk, 0, RspLoc);
1796   ValueIDNum RaxPHIInBlk3(RetBlk, 0, RaxLoc);
1797   DbgOpID LiveInRspID = addValueDbgOp(LiveInRsp);
1798   DbgOpID LiveInRaxID = addValueDbgOp(LiveInRax);
1799   DbgOpID RspPHIInBlk2ID = addValueDbgOp(RspPHIInBlk2);
1800   DbgOpID RspPHIInBlk3ID = addValueDbgOp(RspPHIInBlk3);
1801   DbgOpID RaxPHIInBlk3ID = addValueDbgOp(RaxPHIInBlk3);
1802   DbgOpID ConstZeroID = addConstDbgOp(MachineOperand::CreateImm(0));
1803 
1804   DebugVariable Var(FuncVariable, std::nullopt, nullptr);
1805   DbgValueProperties EmptyProps(EmptyExpr, false, false);
1806   DIExpression *TwoOpExpr =
1807       DIExpression::get(Ctx, {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_arg,
1808                               1, dwarf::DW_OP_plus});
1809   DbgValueProperties TwoOpProps(TwoOpExpr, false, true);
1810   SmallVector<DbgValue, 32> VLiveOuts;
1811   VLiveOuts.resize(4, DbgValue(EmptyProps, DbgValue::Undef));
1812   InstrRefBasedLDV::LiveIdxT VLiveOutIdx;
1813   VLiveOutIdx[MBB0] = &VLiveOuts[0];
1814   VLiveOutIdx[MBB1] = &VLiveOuts[1];
1815   VLiveOutIdx[MBB2] = &VLiveOuts[2];
1816   VLiveOutIdx[MBB3] = &VLiveOuts[3];
1817 
1818   SmallVector<const MachineBasicBlock *, 2> Preds;
1819   for (const auto *Pred : MBB3->predecessors())
1820     Preds.push_back(Pred);
1821 
1822   // Specify the live-outs around the joining block.
1823   MOutLocs[1][0] = LiveInRsp;
1824   MOutLocs[2][0] = LiveInRax;
1825 
1826   bool Result;
1827   SmallVector<DbgOpID> OutValues;
1828 
1829   // Simple case: join two distinct values on entry to the block.
1830   VLiveOuts[1] = DbgValue(LiveInRspID, EmptyProps);
1831   VLiveOuts[2] = DbgValue(LiveInRaxID, EmptyProps);
1832   OutValues.clear();
1833   Result = pickVPHILoc(OutValues, *MBB3, VLiveOutIdx, MOutLocs, Preds);
1834   // Should have picked a PHI in $rsp in block 3.
1835   EXPECT_TRUE(Result);
1836   if (Result) {
1837     EXPECT_EQ(OutValues[0], RspPHIInBlk3ID);
1838   }
1839 
1840   // If the incoming values are swapped between blocks, we should not
1841   // successfully join. The CFG merge would select the right values, but in
1842   // the wrong conditions.
1843   std::swap(VLiveOuts[1], VLiveOuts[2]);
1844   OutValues.clear();
1845   Result = pickVPHILoc(OutValues, *MBB3, VLiveOutIdx, MOutLocs, Preds);
1846   EXPECT_FALSE(Result);
1847 
1848   // Swap back,
1849   std::swap(VLiveOuts[1], VLiveOuts[2]);
1850   // Setting one of these to being a constant should prohibit merging.
1851   VLiveOuts[1].setDbgOpIDs(ConstZeroID);
1852   OutValues.clear();
1853   Result = pickVPHILoc(OutValues, *MBB3, VLiveOutIdx, MOutLocs, Preds);
1854   EXPECT_FALSE(Result);
1855 
1856   // Setting both to being identical constants should result in a valid join
1857   // with a constant value.
1858   VLiveOuts[2] = VLiveOuts[1];
1859   OutValues.clear();
1860   Result = pickVPHILoc(OutValues, *MBB3, VLiveOutIdx, MOutLocs, Preds);
1861   EXPECT_TRUE(Result);
1862   if (Result) {
1863     EXPECT_EQ(OutValues[0], ConstZeroID);
1864   }
1865 
1866   // NoVals shouldn't join with anything else.
1867   VLiveOuts[1] = DbgValue(LiveInRspID, EmptyProps);
1868   VLiveOuts[2] = DbgValue(2, EmptyProps, DbgValue::NoVal);
1869   OutValues.clear();
1870   Result = pickVPHILoc(OutValues, *MBB3, VLiveOutIdx, MOutLocs, Preds);
1871   EXPECT_FALSE(Result);
1872 
1873   // We might merge in another VPHI in such a join. Present pickVPHILoc with
1874   // such a scenario: first, where one incoming edge has a VPHI with no known
1875   // value. This represents an edge where there was a PHI value that can't be
1876   // found in the register file -- we can't subsequently find a PHI here.
1877   VLiveOuts[1] = DbgValue(LiveInRspID, EmptyProps);
1878   VLiveOuts[2] = DbgValue(2, EmptyProps, DbgValue::VPHI);
1879   OutValues.clear();
1880   Result = pickVPHILoc(OutValues, *MBB3, VLiveOutIdx, MOutLocs, Preds);
1881   EXPECT_FALSE(Result);
1882 
1883   // However, if we know the value of the incoming VPHI, we can search for its
1884   // location. Use a PHI machine-value for doing this, as VPHIs should always
1885   // have PHI values, or they should have been eliminated.
1886   MOutLocs[2][0] = RspPHIInBlk2;
1887   VLiveOuts[1] = DbgValue(LiveInRspID, EmptyProps);
1888   VLiveOuts[2] = DbgValue(2, EmptyProps, DbgValue::VPHI);
1889   VLiveOuts[2].setDbgOpIDs(RspPHIInBlk2ID); // Set location where PHI happens.
1890   OutValues.clear();
1891   Result = pickVPHILoc(OutValues, *MBB3, VLiveOutIdx, MOutLocs, Preds);
1892   EXPECT_TRUE(Result);
1893   if (Result) {
1894     EXPECT_EQ(OutValues[0], RspPHIInBlk3ID);
1895   }
1896 
1897   // If that value isn't available from that block, don't join.
1898   MOutLocs[2][0] = LiveInRsp;
1899   OutValues.clear();
1900   Result = pickVPHILoc(OutValues, *MBB3, VLiveOutIdx, MOutLocs, Preds);
1901   EXPECT_FALSE(Result);
1902 
1903   // Check that we don't pick values when the properties disagree, for example
1904   // different indirectness or DIExpression.
1905   MOutLocs[2][0] = LiveInRax;
1906   DIExpression *NewExpr =
1907       DIExpression::prepend(EmptyExpr, DIExpression::ApplyOffset, 4);
1908   DbgValueProperties PropsWithExpr(NewExpr, false, false);
1909   VLiveOuts[1] = DbgValue(LiveInRspID, EmptyProps);
1910   VLiveOuts[2] = DbgValue(LiveInRspID, PropsWithExpr);
1911   OutValues.clear();
1912   Result = pickVPHILoc(OutValues, *MBB3, VLiveOutIdx, MOutLocs, Preds);
1913   EXPECT_FALSE(Result);
1914 
1915   DbgValueProperties PropsWithIndirect(EmptyExpr, true, false);
1916   VLiveOuts[1] = DbgValue(LiveInRspID, EmptyProps);
1917   VLiveOuts[2] = DbgValue(LiveInRspID, PropsWithIndirect);
1918   OutValues.clear();
1919   Result = pickVPHILoc(OutValues, *MBB3, VLiveOutIdx, MOutLocs, Preds);
1920   EXPECT_FALSE(Result);
1921 
1922   // When we have operands with values [A, B] and [B, A], we do not necessarily
1923   // pick identical join locations for each operand if the locations of those
1924   // values differ between incoming basic blocks.
1925   MOutLocs[1][0] = LiveInRsp;
1926   MOutLocs[2][0] = LiveInRax;
1927   MOutLocs[1][1] = LiveInRax;
1928   MOutLocs[2][1] = LiveInRsp;
1929   DbgOpID Locs0[] = {LiveInRspID, LiveInRaxID};
1930   DbgOpID Locs1[] = {LiveInRaxID, LiveInRspID};
1931   VLiveOuts[1] = DbgValue(Locs0, TwoOpProps);
1932   VLiveOuts[2] = DbgValue(Locs1, TwoOpProps);
1933   OutValues.clear();
1934   Result = pickVPHILoc(OutValues, *MBB3, VLiveOutIdx, MOutLocs, Preds);
1935   // Should have picked PHIs in block 3.
1936   EXPECT_TRUE(Result);
1937   if (Result) {
1938     EXPECT_EQ(OutValues[0], RspPHIInBlk3ID);
1939     EXPECT_EQ(OutValues[1], RaxPHIInBlk3ID);
1940   }
1941 
1942   // When joining identical constants for an operand, we should simply keep that
1943   // constant while joining the remaining operands as normal.
1944   DbgOpID Locs2[] = {LiveInRspID, ConstZeroID};
1945   DbgOpID Locs3[] = {LiveInRaxID, ConstZeroID};
1946   VLiveOuts[1] = DbgValue(Locs2, TwoOpProps);
1947   VLiveOuts[2] = DbgValue(Locs3, TwoOpProps);
1948   OutValues.clear();
1949   Result = pickVPHILoc(OutValues, *MBB3, VLiveOutIdx, MOutLocs, Preds);
1950   EXPECT_TRUE(Result);
1951   if (Result) {
1952     EXPECT_EQ(OutValues[0], RspPHIInBlk3ID);
1953     EXPECT_EQ(OutValues[1], ConstZeroID);
1954   }
1955 
1956   // If the debug values have different constants for the same operand, they
1957   // cannot be joined.
1958   DbgOpID ConstOneID = addConstDbgOp(MachineOperand::CreateImm(1));
1959   DbgOpID Locs4[] = {LiveInRaxID, ConstOneID};
1960   VLiveOuts[1] = DbgValue(Locs3, TwoOpProps);
1961   VLiveOuts[2] = DbgValue(Locs4, TwoOpProps);
1962   OutValues.clear();
1963   Result = pickVPHILoc(OutValues, *MBB3, VLiveOutIdx, MOutLocs, Preds);
1964   EXPECT_FALSE(Result);
1965 }
1966 
1967 TEST_F(InstrRefLDVTest, pickVPHILocLoops) {
1968   setupSimpleLoop();
1969   //    entry
1970   //     |
1971   //     |/-----\
1972   //    loopblk |
1973   //     |\-----/
1974   //     |
1975   //     ret
1976 
1977   ASSERT_TRUE(MTracker->getNumLocs() == 1);
1978   LocIdx RspLoc(0);
1979   Register RAX = getRegByName("RAX");
1980   LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX);
1981 
1982   auto [MInLocs, MOutLocs] = allocValueTables(3, 2);
1983 
1984   initValueArray(MOutLocs, 3, 2);
1985 
1986   unsigned EntryBlk = 0, LoopBlk = 1;
1987 
1988   ValueIDNum LiveInRsp(EntryBlk, 0, RspLoc);
1989   ValueIDNum LiveInRax(EntryBlk, 0, RaxLoc);
1990   ValueIDNum RspPHIInBlk1(LoopBlk, 0, RspLoc);
1991   ValueIDNum RaxPHIInBlk1(LoopBlk, 0, RaxLoc);
1992   DbgOpID LiveInRspID = addValueDbgOp(LiveInRsp);
1993   DbgOpID LiveInRaxID = addValueDbgOp(LiveInRax);
1994   DbgOpID RspPHIInBlk1ID = addValueDbgOp(RspPHIInBlk1);
1995   DbgOpID RaxPHIInBlk1ID = addValueDbgOp(RaxPHIInBlk1);
1996 
1997   DebugVariable Var(FuncVariable, std::nullopt, nullptr);
1998   DbgValueProperties EmptyProps(EmptyExpr, false, false);
1999   DIExpression *TwoOpExpr =
2000       DIExpression::get(Ctx, {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_arg,
2001                               1, dwarf::DW_OP_plus});
2002   DbgValueProperties TwoOpProps(TwoOpExpr, false, true);
2003   SmallVector<DbgValue, 32> VLiveOuts;
2004   VLiveOuts.resize(3, DbgValue(EmptyProps, DbgValue::Undef));
2005   InstrRefBasedLDV::LiveIdxT VLiveOutIdx;
2006   VLiveOutIdx[MBB0] = &VLiveOuts[0];
2007   VLiveOutIdx[MBB1] = &VLiveOuts[1];
2008   VLiveOutIdx[MBB2] = &VLiveOuts[2];
2009 
2010   SmallVector<const MachineBasicBlock *, 2> Preds;
2011   for (const auto *Pred : MBB1->predecessors())
2012     Preds.push_back(Pred);
2013 
2014   // Specify the live-outs around the joining block.
2015   MOutLocs[0][0] = LiveInRsp;
2016   MOutLocs[1][0] = LiveInRax;
2017 
2018   bool Result;
2019   SmallVector<DbgOpID> OutValues;
2020 
2021   // See that we can merge as normal on a backedge.
2022   VLiveOuts[0] = DbgValue(LiveInRspID, EmptyProps);
2023   VLiveOuts[1] = DbgValue(LiveInRaxID, EmptyProps);
2024   OutValues.clear();
2025   Result = pickVPHILoc(OutValues, *MBB1, VLiveOutIdx, MOutLocs, Preds);
2026   // Should have picked a PHI in $rsp in block 1.
2027   EXPECT_TRUE(Result);
2028   if (Result) {
2029     EXPECT_EQ(OutValues[0], RspPHIInBlk1ID);
2030   }
2031 
2032   // And that, if the desired values aren't available, we don't merge.
2033   MOutLocs[1][0] = LiveInRsp;
2034   OutValues.clear();
2035   Result = pickVPHILoc(OutValues, *MBB1, VLiveOutIdx, MOutLocs, Preds);
2036   EXPECT_FALSE(Result);
2037 
2038   // Test the backedge behaviour: PHIs that feed back into themselves can
2039   // carry this variables value. Feed in LiveInRsp in both $rsp and $rax
2040   // from the entry block, but only put an appropriate backedge PHI in $rax.
2041   // Only the $rax location can form the correct PHI.
2042   MOutLocs[0][0] = LiveInRsp;
2043   MOutLocs[0][1] = LiveInRsp;
2044   MOutLocs[1][0] = RaxPHIInBlk1;
2045   MOutLocs[1][1] = RaxPHIInBlk1;
2046   VLiveOuts[0] = DbgValue(LiveInRspID, EmptyProps);
2047   // Crucially, a VPHI originating in this block:
2048   VLiveOuts[1] = DbgValue(1, EmptyProps, DbgValue::VPHI);
2049   OutValues.clear();
2050   Result = pickVPHILoc(OutValues, *MBB1, VLiveOutIdx, MOutLocs, Preds);
2051   EXPECT_TRUE(Result);
2052   if (Result) {
2053     EXPECT_EQ(OutValues[0], RaxPHIInBlk1ID);
2054   }
2055 
2056   // Test that we can also find a location when joining a backedge PHI with
2057   // a variadic debug value.
2058   MOutLocs[1][0] = RspPHIInBlk1;
2059   MOutLocs[0][1] = LiveInRax;
2060   DbgOpID Locs0[] = {LiveInRspID, LiveInRaxID};
2061   VLiveOuts[0] = DbgValue(Locs0, TwoOpProps);
2062   // Crucially, a VPHI originating in this block:
2063   VLiveOuts[1] = DbgValue(1, TwoOpProps, DbgValue::VPHI);
2064   OutValues.clear();
2065   Result = pickVPHILoc(OutValues, *MBB1, VLiveOutIdx, MOutLocs, Preds);
2066   EXPECT_TRUE(Result);
2067   if (Result) {
2068     EXPECT_EQ(OutValues[0], RspPHIInBlk1ID);
2069     EXPECT_EQ(OutValues[1], RaxPHIInBlk1ID);
2070   }
2071 
2072   // Merging should not be permitted if there's a usable PHI on the backedge,
2073   // but it's in the wrong place. (Overwrite $rax).
2074   MOutLocs[1][1] = LiveInRax;
2075   VLiveOuts[0] = DbgValue(LiveInRspID, EmptyProps);
2076   OutValues.clear();
2077   Result = pickVPHILoc(OutValues, *MBB1, VLiveOutIdx, MOutLocs, Preds);
2078   EXPECT_FALSE(Result);
2079 
2080   // Additionally, if the VPHI coming back on the loop backedge isn't from
2081   // this block (block 1), we can't merge it.
2082   MOutLocs[1][1] = RaxPHIInBlk1;
2083   VLiveOuts[0] = DbgValue(LiveInRspID, EmptyProps);
2084   VLiveOuts[1] = DbgValue(0, EmptyProps, DbgValue::VPHI);
2085   OutValues.clear();
2086   Result = pickVPHILoc(OutValues, *MBB1, VLiveOutIdx, MOutLocs, Preds);
2087   EXPECT_FALSE(Result);
2088 }
2089 
2090 TEST_F(InstrRefLDVTest, pickVPHILocBadlyNestedLoops) {
2091   // Run some tests similar to pickVPHILocLoops, with more than one backedge,
2092   // and check that we merge correctly over many candidate locations.
2093   setupBadlyNestedLoops();
2094   //           entry
2095   //             |
2096   //           loop1 -o
2097   //             | ^
2098   //             | ^
2099   //           loop2 -o
2100   //             | ^
2101   //             | ^
2102   //           loop3 -o
2103   //             |
2104   //            ret
2105   ASSERT_TRUE(MTracker->getNumLocs() == 1);
2106   LocIdx RspLoc(0);
2107   Register RAX = getRegByName("RAX");
2108   LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX);
2109   Register RBX = getRegByName("RBX");
2110   LocIdx RbxLoc = MTracker->lookupOrTrackRegister(RBX);
2111 
2112   auto [MInLocs, MOutLocs] = allocValueTables(5, 3);
2113 
2114   initValueArray(MOutLocs, 5, 3);
2115 
2116   unsigned EntryBlk = 0, Loop1Blk = 1;
2117 
2118   ValueIDNum LiveInRsp(EntryBlk, 0, RspLoc);
2119   ValueIDNum LiveInRax(EntryBlk, 0, RaxLoc);
2120   ValueIDNum LiveInRbx(EntryBlk, 0, RbxLoc);
2121   ValueIDNum RspPHIInBlk1(Loop1Blk, 0, RspLoc);
2122   ValueIDNum RaxPHIInBlk1(Loop1Blk, 0, RaxLoc);
2123   ValueIDNum RbxPHIInBlk1(Loop1Blk, 0, RbxLoc);
2124   DbgOpID LiveInRspID = addValueDbgOp(LiveInRsp);
2125   DbgOpID LiveInRaxID = addValueDbgOp(LiveInRax);
2126   DbgOpID LiveInRbxID = addValueDbgOp(LiveInRbx);
2127   DbgOpID RspPHIInBlk1ID = addValueDbgOp(RspPHIInBlk1);
2128   addValueDbgOp(RaxPHIInBlk1);
2129   DbgOpID RbxPHIInBlk1ID = addValueDbgOp(RbxPHIInBlk1);
2130 
2131   DebugVariable Var(FuncVariable, std::nullopt, nullptr);
2132   DbgValueProperties EmptyProps(EmptyExpr, false, false);
2133   SmallVector<DbgValue, 32> VLiveOuts;
2134   VLiveOuts.resize(5, DbgValue(EmptyProps, DbgValue::Undef));
2135   InstrRefBasedLDV::LiveIdxT VLiveOutIdx;
2136   VLiveOutIdx[MBB0] = &VLiveOuts[0];
2137   VLiveOutIdx[MBB1] = &VLiveOuts[1];
2138   VLiveOutIdx[MBB2] = &VLiveOuts[2];
2139   VLiveOutIdx[MBB3] = &VLiveOuts[3];
2140   VLiveOutIdx[MBB4] = &VLiveOuts[4];
2141 
2142   // We're going to focus on block 1.
2143   SmallVector<const MachineBasicBlock *, 2> Preds;
2144   for (const auto *Pred : MBB1->predecessors())
2145     Preds.push_back(Pred);
2146 
2147   // Specify the live-outs around the joining block. Incoming edges from the
2148   // entry block, self, and loop2.
2149   MOutLocs[0][0] = LiveInRsp;
2150   MOutLocs[1][0] = LiveInRax;
2151   MOutLocs[2][0] = LiveInRbx;
2152 
2153   bool Result;
2154   SmallVector<DbgOpID> OutValues;
2155 
2156   // See that we can merge as normal on a backedge.
2157   VLiveOuts[0] = DbgValue(LiveInRspID, EmptyProps);
2158   VLiveOuts[1] = DbgValue(LiveInRaxID, EmptyProps);
2159   VLiveOuts[2] = DbgValue(LiveInRbxID, EmptyProps);
2160   OutValues.clear();
2161   Result = pickVPHILoc(OutValues, *MBB1, VLiveOutIdx, MOutLocs, Preds);
2162   // Should have picked a PHI in $rsp in block 1.
2163   EXPECT_TRUE(Result);
2164   if (Result) {
2165     EXPECT_EQ(OutValues[0], RspPHIInBlk1ID);
2166   }
2167 
2168   // Check too that permuting the live-out locations prevents merging
2169   MOutLocs[0][0] = LiveInRax;
2170   MOutLocs[1][0] = LiveInRbx;
2171   MOutLocs[2][0] = LiveInRsp;
2172   OutValues.clear();
2173   Result = pickVPHILoc(OutValues, *MBB1, VLiveOutIdx, MOutLocs, Preds);
2174   EXPECT_FALSE(Result);
2175 
2176   MOutLocs[0][0] = LiveInRsp;
2177   MOutLocs[1][0] = LiveInRax;
2178   MOutLocs[2][0] = LiveInRbx;
2179 
2180   // Feeding a PHI back on one backedge shouldn't merge (block 1 self backedge
2181   // wants LiveInRax).
2182   MOutLocs[1][0] = RspPHIInBlk1;
2183   OutValues.clear();
2184   Result = pickVPHILoc(OutValues, *MBB1, VLiveOutIdx, MOutLocs, Preds);
2185   EXPECT_FALSE(Result);
2186 
2187   // If the variables value on that edge is a VPHI feeding into itself, that's
2188   // fine.
2189   VLiveOuts[0] = DbgValue(LiveInRspID, EmptyProps);
2190   VLiveOuts[1] = DbgValue(1, EmptyProps, DbgValue::VPHI);
2191   VLiveOuts[2] = DbgValue(LiveInRbxID, EmptyProps);
2192   OutValues.clear();
2193   Result = pickVPHILoc(OutValues, *MBB1, VLiveOutIdx, MOutLocs, Preds);
2194   EXPECT_TRUE(Result);
2195   if (Result) {
2196     EXPECT_EQ(OutValues[0], RspPHIInBlk1ID);
2197   }
2198 
2199   // Likewise: the other backedge being a VPHI from block 1 should be accepted.
2200   MOutLocs[2][0] = RspPHIInBlk1;
2201   VLiveOuts[0] = DbgValue(LiveInRspID, EmptyProps);
2202   VLiveOuts[1] = DbgValue(1, EmptyProps, DbgValue::VPHI);
2203   VLiveOuts[2] = DbgValue(1, EmptyProps, DbgValue::VPHI);
2204   OutValues.clear();
2205   Result = pickVPHILoc(OutValues, *MBB1, VLiveOutIdx, MOutLocs, Preds);
2206   EXPECT_TRUE(Result);
2207   if (Result) {
2208     EXPECT_EQ(OutValues[0], RspPHIInBlk1ID);
2209   }
2210 
2211   // Here's where it becomes tricky: we should not merge if there are two
2212   // _distinct_ backedge PHIs. We can't have a PHI that happens in both rsp
2213   // and rax for example. We can only pick one location as the live-in.
2214   MOutLocs[2][0] = RaxPHIInBlk1;
2215   OutValues.clear();
2216   Result = pickVPHILoc(OutValues, *MBB1, VLiveOutIdx, MOutLocs, Preds);
2217   EXPECT_FALSE(Result);
2218 
2219   // The above test sources correct machine-PHI-value from two places. Now
2220   // try with one machine-PHI-value, but placed in two different locations
2221   // on the backedge. Again, we can't merge a location here, there's no
2222   // location that works on all paths.
2223   MOutLocs[0][0] = LiveInRsp;
2224   MOutLocs[1][0] = RspPHIInBlk1;
2225   MOutLocs[2][0] = LiveInRsp;
2226   MOutLocs[2][1] = RspPHIInBlk1;
2227   OutValues.clear();
2228   Result = pickVPHILoc(OutValues, *MBB1, VLiveOutIdx, MOutLocs, Preds);
2229   EXPECT_FALSE(Result);
2230 
2231   // Scatter various PHI values across the available locations. Only rbx (loc 2)
2232   // has the right value in both backedges -- that's the loc that should be
2233   // picked.
2234   MOutLocs[0][2] = LiveInRsp;
2235   MOutLocs[1][0] = RspPHIInBlk1;
2236   MOutLocs[1][1] = RaxPHIInBlk1;
2237   MOutLocs[1][2] = RbxPHIInBlk1;
2238   MOutLocs[2][0] = LiveInRsp;
2239   MOutLocs[2][1] = RspPHIInBlk1;
2240   MOutLocs[2][2] = RbxPHIInBlk1;
2241   OutValues.clear();
2242   Result = pickVPHILoc(OutValues, *MBB1, VLiveOutIdx, MOutLocs, Preds);
2243   EXPECT_TRUE(Result);
2244   if (Result) {
2245     EXPECT_EQ(OutValues[0], RbxPHIInBlk1ID);
2246   }
2247 }
2248 
2249 TEST_F(InstrRefLDVTest, vlocJoinDiamond) {
2250   //        entry
2251   //        /  \
2252   //      br1  br2
2253   //        \  /
2254   //         ret
2255   setupDiamondBlocks();
2256 
2257   ASSERT_TRUE(MTracker->getNumLocs() == 1);
2258   LocIdx RspLoc(0);
2259   Register RAX = getRegByName("RAX");
2260   MTracker->lookupOrTrackRegister(RAX);
2261 
2262   DbgOpID LiveInRspID = DbgOpID(false, 0);
2263   DbgOpID LiveInRaxID = DbgOpID(false, 1);
2264 
2265   DebugVariable Var(FuncVariable, std::nullopt, nullptr);
2266   DbgValueProperties EmptyProps(EmptyExpr, false, false);
2267   SmallVector<DbgValue, 32> VLiveOuts;
2268   VLiveOuts.resize(4, DbgValue(EmptyProps, DbgValue::Undef));
2269   InstrRefBasedLDV::LiveIdxT VLiveOutIdx;
2270   VLiveOutIdx[MBB0] = &VLiveOuts[0];
2271   VLiveOutIdx[MBB1] = &VLiveOuts[1];
2272   VLiveOutIdx[MBB2] = &VLiveOuts[2];
2273   VLiveOutIdx[MBB3] = &VLiveOuts[3];
2274 
2275   SmallPtrSet<const MachineBasicBlock *, 8> AllBlocks;
2276   AllBlocks.insert(MBB0);
2277   AllBlocks.insert(MBB1);
2278   AllBlocks.insert(MBB2);
2279   AllBlocks.insert(MBB3);
2280 
2281   SmallVector<const MachineBasicBlock *, 2> Preds;
2282   for (const auto *Pred : MBB3->predecessors())
2283     Preds.push_back(Pred);
2284 
2285   SmallSet<DebugVariable, 4> AllVars;
2286   AllVars.insert(Var);
2287 
2288   // vlocJoin is here to propagate incoming values, and eliminate PHIs. Start
2289   // off by propagating a value into the merging block, number 3.
2290   DbgValue JoinedLoc = DbgValue(3, EmptyProps, DbgValue::NoVal);
2291   VLiveOuts[1] = DbgValue(LiveInRspID, EmptyProps);
2292   VLiveOuts[2] = DbgValue(LiveInRspID, EmptyProps);
2293   bool Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, JoinedLoc);
2294   EXPECT_TRUE(Result); // Output locs should have changed.
2295   EXPECT_EQ(JoinedLoc.Kind, DbgValue::Def);
2296   EXPECT_EQ(JoinedLoc.getDbgOpID(0), LiveInRspID);
2297 
2298   // And if we did it a second time, leaving the live-ins as it was, then
2299   // we should report no change.
2300   Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, JoinedLoc);
2301   EXPECT_FALSE(Result);
2302 
2303   // If the live-in variable values are different, but there's no PHI placed
2304   // in this block, then just pick a location. It should be the first (in RPO)
2305   // predecessor to avoid being a backedge.
2306   VLiveOuts[1] = DbgValue(LiveInRspID, EmptyProps);
2307   VLiveOuts[2] = DbgValue(LiveInRaxID, EmptyProps);
2308   JoinedLoc = DbgValue(3, EmptyProps, DbgValue::NoVal);
2309   Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, JoinedLoc);
2310   EXPECT_TRUE(Result);
2311   EXPECT_EQ(JoinedLoc.Kind, DbgValue::Def);
2312   // RPO is blocks 0 2 1 3, so LiveInRax is picked as the first predecessor
2313   // of this join.
2314   EXPECT_EQ(JoinedLoc.getDbgOpID(0), LiveInRaxID);
2315 
2316   // No tests for whether vlocJoin will pass-through a variable with differing
2317   // expressions / properties. Those can only come about due to assignments; and
2318   // for any assignment at all, a PHI should have been placed at the dominance
2319   // frontier. We rely on the IDF calculator being accurate (which is OK,
2320   // because so does the rest of LLVM).
2321 
2322   // Try placing a PHI. With differing input values (LiveInRsp, LiveInRax),
2323   // this PHI should not be eliminated.
2324   JoinedLoc = DbgValue(3, EmptyProps, DbgValue::VPHI);
2325   Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, JoinedLoc);
2326   // Expect no change.
2327   EXPECT_FALSE(Result);
2328   EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
2329   // This should not have been assigned a fixed value.
2330   EXPECT_EQ(JoinedLoc.getDbgOpID(0), DbgOpID::UndefID);
2331   EXPECT_EQ(JoinedLoc.BlockNo, 3);
2332 
2333   // Try a simple PHI elimination. Put a PHI in block 3, but LiveInRsp on both
2334   // incoming edges. Re-load in and out-locs with unrelated values; they're
2335   // irrelevant.
2336   VLiveOuts[1] = DbgValue(LiveInRspID, EmptyProps);
2337   VLiveOuts[2] = DbgValue(LiveInRspID, EmptyProps);
2338   JoinedLoc = DbgValue(3, EmptyProps, DbgValue::VPHI);
2339   Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, JoinedLoc);
2340   EXPECT_TRUE(Result);
2341   EXPECT_EQ(JoinedLoc.Kind, DbgValue::Def);
2342   EXPECT_EQ(JoinedLoc.getDbgOpID(0), LiveInRspID);
2343 
2344   // Try the same PHI elimination but with one incoming value being a VPHI
2345   // referring to the same value.
2346   VLiveOuts[1] = DbgValue(LiveInRspID, EmptyProps);
2347   VLiveOuts[2] = DbgValue(2, EmptyProps, DbgValue::VPHI);
2348   VLiveOuts[2].setDbgOpIDs(LiveInRspID);
2349   JoinedLoc = DbgValue(3, EmptyProps, DbgValue::VPHI);
2350   Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, JoinedLoc);
2351   EXPECT_TRUE(Result);
2352   EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
2353   EXPECT_EQ(JoinedLoc.getDbgOpID(0), LiveInRspID);
2354 
2355   // If the "current" live-in is a VPHI, but not a VPHI generated in the current
2356   // block, then it's the remains of an earlier value propagation. We should
2357   // value propagate through this merge. Even if the current incoming values
2358   // disagree, because we've previously determined any VPHI here is redundant.
2359   VLiveOuts[1] = DbgValue(LiveInRspID, EmptyProps);
2360   VLiveOuts[2] = DbgValue(LiveInRaxID, EmptyProps);
2361   JoinedLoc = DbgValue(2, EmptyProps, DbgValue::VPHI);
2362   Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, JoinedLoc);
2363   EXPECT_TRUE(Result);
2364   EXPECT_EQ(JoinedLoc.Kind, DbgValue::Def);
2365   EXPECT_EQ(JoinedLoc.getDbgOpID(0), LiveInRaxID); // from block 2
2366 
2367   // The above test, but test that we will install one value-propagated VPHI
2368   // over another.
2369   VLiveOuts[1] = DbgValue(LiveInRspID, EmptyProps);
2370   VLiveOuts[2] = DbgValue(0, EmptyProps, DbgValue::VPHI);
2371   JoinedLoc = DbgValue(2, EmptyProps, DbgValue::VPHI);
2372   Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, JoinedLoc);
2373   EXPECT_TRUE(Result);
2374   EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
2375   EXPECT_EQ(JoinedLoc.BlockNo, 0);
2376 
2377   // We shouldn't eliminate PHIs when properties disagree.
2378   DbgValueProperties PropsWithIndirect(EmptyExpr, true, false);
2379   VLiveOuts[1] = DbgValue(LiveInRspID, EmptyProps);
2380   VLiveOuts[2] = DbgValue(LiveInRspID, PropsWithIndirect);
2381   JoinedLoc = DbgValue(3, EmptyProps, DbgValue::VPHI);
2382   Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, JoinedLoc);
2383   EXPECT_FALSE(Result);
2384   EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
2385   EXPECT_EQ(JoinedLoc.BlockNo, 3);
2386 
2387   // Even if properties disagree, we should still value-propagate if there's no
2388   // PHI to be eliminated. The disagreeing values should work themselves out,
2389   // seeing how we've determined no PHI is necessary.
2390   VLiveOuts[1] = DbgValue(LiveInRspID, EmptyProps);
2391   VLiveOuts[2] = DbgValue(LiveInRspID, PropsWithIndirect);
2392   JoinedLoc = DbgValue(2, EmptyProps, DbgValue::VPHI);
2393   Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, JoinedLoc);
2394   EXPECT_TRUE(Result);
2395   EXPECT_EQ(JoinedLoc.Kind, DbgValue::Def);
2396   EXPECT_EQ(JoinedLoc.getDbgOpID(0), LiveInRspID);
2397   // Also check properties come from block 2, the first RPO predecessor to block
2398   // three.
2399   EXPECT_EQ(JoinedLoc.Properties, PropsWithIndirect);
2400 
2401   // Again, disagreeing properties, this time the expr, should cause a PHI to
2402   // not be eliminated.
2403   DIExpression *NewExpr =
2404       DIExpression::prepend(EmptyExpr, DIExpression::ApplyOffset, 4);
2405   DbgValueProperties PropsWithExpr(NewExpr, false, false);
2406   VLiveOuts[1] = DbgValue(LiveInRspID, EmptyProps);
2407   VLiveOuts[2] = DbgValue(LiveInRspID, PropsWithExpr);
2408   JoinedLoc = DbgValue(3, EmptyProps, DbgValue::VPHI);
2409   Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, JoinedLoc);
2410   EXPECT_FALSE(Result);
2411 
2412   // Try placing a PHI with variadic debug values. With differing input values
2413   // (LiveInRsp, LiveInRax), this PHI should not be eliminated.
2414   DIExpression *TwoOpExpr =
2415       DIExpression::get(Ctx, {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_arg,
2416                               1, dwarf::DW_OP_plus});
2417   DbgValueProperties TwoOpProps(TwoOpExpr, false, true);
2418   DbgOpID Locs0[] = {LiveInRspID, LiveInRaxID};
2419   DbgOpID Locs1[] = {LiveInRaxID, LiveInRspID};
2420   JoinedLoc = DbgValue(3, TwoOpProps, DbgValue::VPHI);
2421   VLiveOuts[1] = DbgValue(Locs0, TwoOpProps);
2422   VLiveOuts[2] = DbgValue(Locs1, TwoOpProps);
2423   Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, JoinedLoc);
2424   // Expect no change.
2425   EXPECT_FALSE(Result);
2426   EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
2427   // This should not have been assigned a fixed value.
2428   EXPECT_EQ(JoinedLoc.getDbgOpID(0), DbgOpID::UndefID);
2429   EXPECT_EQ(JoinedLoc.BlockNo, 3);
2430 }
2431 
2432 TEST_F(InstrRefLDVTest, vlocJoinLoops) {
2433   setupSimpleLoop();
2434   //    entry
2435   //     |
2436   //     |/-----\
2437   //    loopblk |
2438   //     |\-----/
2439   //     |
2440   //     ret
2441   ASSERT_TRUE(MTracker->getNumLocs() == 1);
2442   LocIdx RspLoc(0);
2443   Register RAX = getRegByName("RAX");
2444   MTracker->lookupOrTrackRegister(RAX);
2445 
2446   DbgOpID LiveInRspID = DbgOpID(false, 0);
2447   DbgOpID LiveInRaxID = DbgOpID(false, 1);
2448 
2449   DebugVariable Var(FuncVariable, std::nullopt, nullptr);
2450   DbgValueProperties EmptyProps(EmptyExpr, false, false);
2451   SmallVector<DbgValue, 32> VLiveOuts;
2452   VLiveOuts.resize(3, DbgValue(EmptyProps, DbgValue::Undef));
2453   InstrRefBasedLDV::LiveIdxT VLiveOutIdx;
2454   VLiveOutIdx[MBB0] = &VLiveOuts[0];
2455   VLiveOutIdx[MBB1] = &VLiveOuts[1];
2456   VLiveOutIdx[MBB2] = &VLiveOuts[2];
2457 
2458   SmallPtrSet<const MachineBasicBlock *, 8> AllBlocks;
2459   AllBlocks.insert(MBB0);
2460   AllBlocks.insert(MBB1);
2461   AllBlocks.insert(MBB2);
2462 
2463   SmallVector<const MachineBasicBlock *, 2> Preds;
2464   for (const auto *Pred : MBB1->predecessors())
2465     Preds.push_back(Pred);
2466 
2467   SmallSet<DebugVariable, 4> AllVars;
2468   AllVars.insert(Var);
2469 
2470   // Test some back-edge-specific behaviours of vloc join. Mostly: the fact that
2471   // VPHIs that arrive on backedges can be eliminated, despite having different
2472   // values to the predecessor.
2473 
2474   // First: when there's no VPHI placed already, propagate the live-in value of
2475   // the first RPO predecessor.
2476   VLiveOuts[0] = DbgValue(LiveInRspID, EmptyProps);
2477   VLiveOuts[1] = DbgValue(LiveInRaxID, EmptyProps);
2478   DbgValue JoinedLoc = DbgValue(LiveInRaxID, EmptyProps);
2479   bool Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, JoinedLoc);
2480   EXPECT_TRUE(Result);
2481   EXPECT_EQ(JoinedLoc.Kind, DbgValue::Def);
2482   EXPECT_EQ(JoinedLoc.getDbgOpID(0), LiveInRspID);
2483 
2484   // If there is a VPHI: don't elimiante it if there are disagreeing values.
2485   VLiveOuts[0] = DbgValue(LiveInRspID, EmptyProps);
2486   VLiveOuts[1] = DbgValue(LiveInRaxID, EmptyProps);
2487   JoinedLoc = DbgValue(1, EmptyProps, DbgValue::VPHI);
2488   Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, JoinedLoc);
2489   EXPECT_FALSE(Result);
2490   EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
2491   EXPECT_EQ(JoinedLoc.BlockNo, 1);
2492 
2493   // If we feed this VPHI back into itself though, we can eliminate it.
2494   VLiveOuts[0] = DbgValue(LiveInRspID, EmptyProps);
2495   VLiveOuts[1] = DbgValue(1, EmptyProps, DbgValue::VPHI);
2496   JoinedLoc = DbgValue(1, EmptyProps, DbgValue::VPHI);
2497   Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, JoinedLoc);
2498   EXPECT_TRUE(Result);
2499   EXPECT_EQ(JoinedLoc.Kind, DbgValue::Def);
2500   EXPECT_EQ(JoinedLoc.getDbgOpID(0), LiveInRspID);
2501 
2502   // Don't eliminate backedge VPHIs if the predecessors have different
2503   // properties.
2504   DIExpression *NewExpr =
2505       DIExpression::prepend(EmptyExpr, DIExpression::ApplyOffset, 4);
2506   DbgValueProperties PropsWithExpr(NewExpr, false, false);
2507   VLiveOuts[0] = DbgValue(LiveInRspID, EmptyProps);
2508   VLiveOuts[1] = DbgValue(1, PropsWithExpr, DbgValue::VPHI);
2509   JoinedLoc = DbgValue(1, EmptyProps, DbgValue::VPHI);
2510   Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, JoinedLoc);
2511   EXPECT_FALSE(Result);
2512   EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
2513   EXPECT_EQ(JoinedLoc.BlockNo, 1);
2514 
2515   // Backedges with VPHIs, but from the wrong block, shouldn't be eliminated.
2516   VLiveOuts[0] = DbgValue(LiveInRspID, EmptyProps);
2517   VLiveOuts[1] = DbgValue(0, EmptyProps, DbgValue::VPHI);
2518   JoinedLoc = DbgValue(1, EmptyProps, DbgValue::VPHI);
2519   Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, JoinedLoc);
2520   EXPECT_FALSE(Result);
2521   EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
2522   EXPECT_EQ(JoinedLoc.BlockNo, 1);
2523 }
2524 
2525 TEST_F(InstrRefLDVTest, vlocJoinBadlyNestedLoops) {
2526   // Test PHI elimination in the presence of multiple backedges.
2527   setupBadlyNestedLoops();
2528   //           entry
2529   //             |
2530   //           loop1 -o
2531   //             | ^
2532   //             | ^
2533   //           loop2 -o
2534   //             | ^
2535   //             | ^
2536   //           loop3 -o
2537   //             |
2538   //            ret
2539   ASSERT_TRUE(MTracker->getNumLocs() == 1);
2540   LocIdx RspLoc(0);
2541   Register RAX = getRegByName("RAX");
2542   MTracker->lookupOrTrackRegister(RAX);
2543   Register RBX = getRegByName("RBX");
2544   MTracker->lookupOrTrackRegister(RBX);
2545 
2546   DbgOpID LiveInRspID = DbgOpID(false, 0);
2547   DbgOpID LiveInRaxID = DbgOpID(false, 1);
2548   DbgOpID LiveInRbxID = DbgOpID(false, 2);
2549 
2550   DebugVariable Var(FuncVariable, std::nullopt, nullptr);
2551   DbgValueProperties EmptyProps(EmptyExpr, false, false);
2552   SmallVector<DbgValue, 32> VLiveOuts;
2553   VLiveOuts.resize(5, DbgValue(EmptyProps, DbgValue::Undef));
2554   InstrRefBasedLDV::LiveIdxT VLiveOutIdx;
2555   VLiveOutIdx[MBB0] = &VLiveOuts[0];
2556   VLiveOutIdx[MBB1] = &VLiveOuts[1];
2557   VLiveOutIdx[MBB2] = &VLiveOuts[2];
2558   VLiveOutIdx[MBB3] = &VLiveOuts[3];
2559   VLiveOutIdx[MBB4] = &VLiveOuts[4];
2560 
2561   SmallPtrSet<const MachineBasicBlock *, 8> AllBlocks;
2562   AllBlocks.insert(MBB0);
2563   AllBlocks.insert(MBB1);
2564   AllBlocks.insert(MBB2);
2565   AllBlocks.insert(MBB3);
2566   AllBlocks.insert(MBB4);
2567 
2568   // We're going to focus on block 1.
2569   SmallVector<const MachineBasicBlock *, 3> Preds;
2570   for (const auto *Pred : MBB1->predecessors())
2571     Preds.push_back(Pred);
2572 
2573   SmallSet<DebugVariable, 4> AllVars;
2574   AllVars.insert(Var);
2575 
2576   // Test a normal VPHI isn't eliminated.
2577   VLiveOuts[0] = DbgValue(LiveInRspID, EmptyProps);
2578   VLiveOuts[1] = DbgValue(LiveInRaxID, EmptyProps);
2579   VLiveOuts[2] = DbgValue(LiveInRbxID, EmptyProps);
2580   DbgValue JoinedLoc = DbgValue(1, EmptyProps, DbgValue::VPHI);
2581   bool Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, JoinedLoc);
2582   EXPECT_FALSE(Result);
2583   EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
2584   EXPECT_EQ(JoinedLoc.BlockNo, 1);
2585 
2586   // Common VPHIs on backedges should merge.
2587   VLiveOuts[0] = DbgValue(LiveInRspID, EmptyProps);
2588   VLiveOuts[1] = DbgValue(1, EmptyProps, DbgValue::VPHI);
2589   VLiveOuts[2] = DbgValue(1, EmptyProps, DbgValue::VPHI);
2590   JoinedLoc = DbgValue(1, EmptyProps, DbgValue::VPHI);
2591   Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, JoinedLoc);
2592   EXPECT_TRUE(Result);
2593   EXPECT_EQ(JoinedLoc.Kind, DbgValue::Def);
2594   EXPECT_EQ(JoinedLoc.getDbgOpID(0), LiveInRspID);
2595 
2596   // They shouldn't merge if one of their properties is different.
2597   DbgValueProperties PropsWithIndirect(EmptyExpr, true, false);
2598   VLiveOuts[0] = DbgValue(LiveInRspID, EmptyProps);
2599   VLiveOuts[1] = DbgValue(1, EmptyProps, DbgValue::VPHI);
2600   VLiveOuts[2] = DbgValue(1, PropsWithIndirect, DbgValue::VPHI);
2601   JoinedLoc = DbgValue(1, EmptyProps, DbgValue::VPHI);
2602   Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, JoinedLoc);
2603   EXPECT_FALSE(Result);
2604   EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
2605   EXPECT_EQ(JoinedLoc.BlockNo, 1);
2606 
2607   // VPHIs from different blocks should not merge.
2608   VLiveOuts[0] = DbgValue(LiveInRspID, EmptyProps);
2609   VLiveOuts[1] = DbgValue(1, EmptyProps, DbgValue::VPHI);
2610   VLiveOuts[2] = DbgValue(2, EmptyProps, DbgValue::VPHI);
2611   JoinedLoc = DbgValue(1, EmptyProps, DbgValue::VPHI);
2612   Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, JoinedLoc);
2613   EXPECT_FALSE(Result);
2614   EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
2615   EXPECT_EQ(JoinedLoc.BlockNo, 1);
2616 }
2617 
2618 // Above are tests for picking VPHI locations, and eliminating VPHIs. No
2619 // unit-tests are written for evaluating the transfer function as that's
2620 // pretty straight forwards, or applying VPHI-location-picking to live-ins.
2621 // Instead, pre-set some machine locations and apply buildVLocValueMap to the
2622 // existing CFG patterns.
2623 TEST_F(InstrRefLDVTest, VLocSingleBlock) {
2624   setupSingleBlock();
2625 
2626   ASSERT_TRUE(MTracker->getNumLocs() == 1);
2627   LocIdx RspLoc(0);
2628 
2629   auto [MInLocs, MOutLocs] = allocValueTables(1, 2);
2630 
2631   ValueIDNum LiveInRsp = ValueIDNum(0, 0, RspLoc);
2632   DbgOpID LiveInRspID = addValueDbgOp(LiveInRsp);
2633   MInLocs[0][0] = MOutLocs[0][0] = LiveInRsp;
2634 
2635   DebugVariable Var(FuncVariable, std::nullopt, nullptr);
2636   DebugVariableID VarID = LDV->getDVMap().insertDVID(Var, OutermostLoc);
2637   DbgValueProperties EmptyProps(EmptyExpr, false, false);
2638 
2639   SmallSet<DebugVariableID, 4> AllVars;
2640   AllVars.insert(VarID);
2641 
2642   // Mild hack: rather than constructing machine instructions in each block
2643   // and creating lexical scopes across them, instead just tell
2644   // buildVLocValueMap that there's an assignment in every block. That makes
2645   // every block in scope.
2646   SmallPtrSet<MachineBasicBlock *, 4> AssignBlocks;
2647   AssignBlocks.insert(MBB0);
2648 
2649   SmallVector<VLocTracker, 1> VLocs;
2650   VLocs.resize(1, VLocTracker(LDV->getDVMap(), Overlaps, EmptyExpr));
2651 
2652   InstrRefBasedLDV::LiveInsT Output;
2653 
2654   // Test that, with no assignments at all, no mappings are created for the
2655   // variable in this function.
2656   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
2657                     MOutLocs, MInLocs, VLocs);
2658   EXPECT_EQ(Output.size(), 0ul);
2659 
2660   // If we put an assignment in the transfer function, that should... well,
2661   // do nothing, because we don't store the live-outs.
2662   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
2663   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
2664                     MOutLocs, MInLocs, VLocs);
2665   EXPECT_EQ(Output.size(), 0ul);
2666 
2667   // There is pretty much nothing else of interest to test with a single block.
2668   // It's not relevant to the SSA-construction parts of variable values.
2669 }
2670 
2671 TEST_F(InstrRefLDVTest, VLocDiamondBlocks) {
2672   setupDiamondBlocks();
2673   //        entry
2674   //        /  \
2675   //      br1  br2
2676   //        \  /
2677   //         ret
2678 
2679   ASSERT_TRUE(MTracker->getNumLocs() == 1);
2680   LocIdx RspLoc(0);
2681   Register RAX = getRegByName("RAX");
2682   LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX);
2683 
2684   unsigned EntryBlk = 0, RetBlk = 3;
2685 
2686   ValueIDNum LiveInRsp = ValueIDNum(EntryBlk, 0, RspLoc);
2687   ValueIDNum LiveInRax = ValueIDNum(EntryBlk, 0, RaxLoc);
2688   ValueIDNum RspPHIInBlk3 = ValueIDNum(RetBlk, 0, RspLoc);
2689   DbgOpID LiveInRspID = addValueDbgOp(LiveInRsp);
2690   DbgOpID LiveInRaxID = addValueDbgOp(LiveInRax);
2691   DbgOpID RspPHIInBlk3ID = addValueDbgOp(RspPHIInBlk3);
2692 
2693   auto [MInLocs, MOutLocs] = allocValueTables(4, 2);
2694 
2695   initValueArray(MInLocs, 4, 2);
2696   initValueArray(MOutLocs, 4, 2);
2697 
2698   DebugVariable Var(FuncVariable, std::nullopt, nullptr);
2699   DebugVariableID VarID = LDV->getDVMap().insertDVID(Var, OutermostLoc);
2700   DbgValueProperties EmptyProps(EmptyExpr, false, false);
2701 
2702   SmallSet<DebugVariableID, 4> AllVars;
2703   AllVars.insert(VarID);
2704 
2705   // Mild hack: rather than constructing machine instructions in each block
2706   // and creating lexical scopes across them, instead just tell
2707   // buildVLocValueMap that there's an assignment in every block. That makes
2708   // every block in scope.
2709   SmallPtrSet<MachineBasicBlock *, 4> AssignBlocks;
2710   AssignBlocks.insert(MBB0);
2711   AssignBlocks.insert(MBB1);
2712   AssignBlocks.insert(MBB2);
2713   AssignBlocks.insert(MBB3);
2714 
2715   SmallVector<VLocTracker, 1> VLocs;
2716   VLocs.resize(4, VLocTracker(LDV->getDVMap(), Overlaps, EmptyExpr));
2717 
2718   InstrRefBasedLDV::LiveInsT Output;
2719 
2720   // Start off with LiveInRsp in every location.
2721   for (unsigned int I = 0; I < 4; ++I) {
2722     MInLocs[I][0] = MInLocs[I][1] = LiveInRsp;
2723     MOutLocs[I][0] = MOutLocs[I][1] = LiveInRsp;
2724   }
2725 
2726   auto ClearOutputs = [&]() {
2727     for (auto &Elem : Output)
2728       Elem.clear();
2729   };
2730   Output.resize(4);
2731 
2732   // No assignments -> no values.
2733   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
2734                     MOutLocs, MInLocs, VLocs);
2735   EXPECT_EQ(Output[0].size(), 0ul);
2736   EXPECT_EQ(Output[1].size(), 0ul);
2737   EXPECT_EQ(Output[2].size(), 0ul);
2738   EXPECT_EQ(Output[3].size(), 0ul);
2739 
2740   // An assignment in the end block should also not affect other blocks; or
2741   // produce any live-ins.
2742   VLocs[3].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
2743   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
2744                     MOutLocs, MInLocs, VLocs);
2745   EXPECT_EQ(Output[0].size(), 0ul);
2746   EXPECT_EQ(Output[1].size(), 0ul);
2747   EXPECT_EQ(Output[2].size(), 0ul);
2748   EXPECT_EQ(Output[3].size(), 0ul);
2749   ClearOutputs();
2750 
2751   // Assignments in either of the side-of-diamond blocks should also not be
2752   // propagated anywhere.
2753   VLocs[3].Vars.clear();
2754   VLocs[2].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
2755   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
2756                     MOutLocs, MInLocs, VLocs);
2757   EXPECT_EQ(Output[0].size(), 0ul);
2758   EXPECT_EQ(Output[1].size(), 0ul);
2759   EXPECT_EQ(Output[2].size(), 0ul);
2760   EXPECT_EQ(Output[3].size(), 0ul);
2761   VLocs[2].Vars.clear();
2762   ClearOutputs();
2763 
2764   VLocs[1].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
2765   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
2766                     MOutLocs, MInLocs, VLocs);
2767   EXPECT_EQ(Output[0].size(), 0ul);
2768   EXPECT_EQ(Output[1].size(), 0ul);
2769   EXPECT_EQ(Output[2].size(), 0ul);
2770   EXPECT_EQ(Output[3].size(), 0ul);
2771   VLocs[1].Vars.clear();
2772   ClearOutputs();
2773 
2774   // However: putting an assignment in the first block should propagate variable
2775   // values through to all other blocks, as it dominates.
2776   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
2777   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
2778                     MOutLocs, MInLocs, VLocs);
2779   EXPECT_EQ(Output[0].size(), 0ul);
2780   ASSERT_EQ(Output[1].size(), 1ul);
2781   ASSERT_EQ(Output[2].size(), 1ul);
2782   ASSERT_EQ(Output[3].size(), 1ul);
2783   EXPECT_EQ(Output[1][0].second.Kind, DbgValue::Def);
2784   EXPECT_EQ(Output[1][0].second.getDbgOpID(0), LiveInRspID);
2785   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
2786   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), LiveInRspID);
2787   EXPECT_EQ(Output[3][0].second.Kind, DbgValue::Def);
2788   EXPECT_EQ(Output[3][0].second.getDbgOpID(0), LiveInRspID);
2789   ClearOutputs();
2790   VLocs[0].Vars.clear();
2791 
2792   // Additionally, even if that value isn't available in the register file, it
2793   // should still be propagated, as buildVLocValueMap shouldn't care about
2794   // what's in the registers (except for PHIs).
2795   // values through to all other blocks, as it dominates.
2796   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRaxID, EmptyProps)});
2797   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
2798                     MOutLocs, MInLocs, VLocs);
2799   EXPECT_EQ(Output[0].size(), 0ul);
2800   ASSERT_EQ(Output[1].size(), 1ul);
2801   ASSERT_EQ(Output[2].size(), 1ul);
2802   ASSERT_EQ(Output[3].size(), 1ul);
2803   EXPECT_EQ(Output[1][0].second.Kind, DbgValue::Def);
2804   EXPECT_EQ(Output[1][0].second.getDbgOpID(0), LiveInRaxID);
2805   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
2806   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), LiveInRaxID);
2807   EXPECT_EQ(Output[3][0].second.Kind, DbgValue::Def);
2808   EXPECT_EQ(Output[3][0].second.getDbgOpID(0), LiveInRaxID);
2809   ClearOutputs();
2810   VLocs[0].Vars.clear();
2811 
2812   // We should get a live-in to the merging block, if there are two assigns of
2813   // the same value in either side of the diamond.
2814   VLocs[1].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
2815   VLocs[2].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
2816   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
2817                     MOutLocs, MInLocs, VLocs);
2818   EXPECT_EQ(Output[0].size(), 0ul);
2819   EXPECT_EQ(Output[1].size(), 0ul);
2820   EXPECT_EQ(Output[2].size(), 0ul);
2821   ASSERT_EQ(Output[3].size(), 1ul);
2822   EXPECT_EQ(Output[3][0].second.Kind, DbgValue::Def);
2823   EXPECT_EQ(Output[3][0].second.getDbgOpID(0), LiveInRspID);
2824   ClearOutputs();
2825   VLocs[1].Vars.clear();
2826   VLocs[2].Vars.clear();
2827 
2828   // If we assign a value in the entry block, then 'undef' on a branch, we
2829   // shouldn't have a live-in in the merge block.
2830   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
2831   VLocs[1].Vars.insert({VarID, DbgValue(EmptyProps, DbgValue::Undef)});
2832   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
2833                     MOutLocs, MInLocs, VLocs);
2834   EXPECT_EQ(Output[0].size(), 0ul);
2835   ASSERT_EQ(Output[1].size(), 1ul);
2836   ASSERT_EQ(Output[2].size(), 1ul);
2837   EXPECT_EQ(Output[3].size(), 0ul);
2838   EXPECT_EQ(Output[1][0].second.Kind, DbgValue::Def);
2839   EXPECT_EQ(Output[1][0].second.getDbgOpID(0), LiveInRspID);
2840   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
2841   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), LiveInRspID);
2842   ClearOutputs();
2843   VLocs[0].Vars.clear();
2844   VLocs[1].Vars.clear();
2845 
2846   // Having different values joining into the merge block should mean we have
2847   // no live-in in that block. Block ones LiveInRax value doesn't appear as a
2848   // live-in anywhere, it's block internal.
2849   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
2850   VLocs[1].Vars.insert({VarID, DbgValue(LiveInRaxID, EmptyProps)});
2851   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
2852                     MOutLocs, MInLocs, VLocs);
2853   EXPECT_EQ(Output[0].size(), 0ul);
2854   ASSERT_EQ(Output[1].size(), 1ul);
2855   ASSERT_EQ(Output[2].size(), 1ul);
2856   EXPECT_EQ(Output[3].size(), 0ul);
2857   EXPECT_EQ(Output[1][0].second.Kind, DbgValue::Def);
2858   EXPECT_EQ(Output[1][0].second.getDbgOpID(0), LiveInRspID);
2859   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
2860   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), LiveInRspID);
2861   ClearOutputs();
2862   VLocs[0].Vars.clear();
2863   VLocs[1].Vars.clear();
2864 
2865   // But on the other hand, if there's a location in the register file where
2866   // those two values can be joined, do so.
2867   MOutLocs[1][0] = LiveInRax;
2868   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
2869   VLocs[1].Vars.insert({VarID, DbgValue(LiveInRaxID, EmptyProps)});
2870   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
2871                     MOutLocs, MInLocs, VLocs);
2872   EXPECT_EQ(Output[0].size(), 0ul);
2873   ASSERT_EQ(Output[1].size(), 1ul);
2874   ASSERT_EQ(Output[2].size(), 1ul);
2875   ASSERT_EQ(Output[3].size(), 1ul);
2876   EXPECT_EQ(Output[1][0].second.Kind, DbgValue::Def);
2877   EXPECT_EQ(Output[1][0].second.getDbgOpID(0), LiveInRspID);
2878   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
2879   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), LiveInRspID);
2880   EXPECT_EQ(Output[3][0].second.Kind, DbgValue::Def);
2881   EXPECT_EQ(Output[3][0].second.getDbgOpID(0), RspPHIInBlk3ID);
2882   ClearOutputs();
2883   VLocs[0].Vars.clear();
2884   VLocs[1].Vars.clear();
2885 }
2886 
2887 TEST_F(InstrRefLDVTest, VLocSimpleLoop) {
2888   setupSimpleLoop();
2889   //    entry
2890   //     |
2891   //     |/-----\
2892   //    loopblk |
2893   //     |\-----/
2894   //     |
2895   //     ret
2896 
2897   ASSERT_TRUE(MTracker->getNumLocs() == 1);
2898   LocIdx RspLoc(0);
2899   Register RAX = getRegByName("RAX");
2900   LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX);
2901 
2902   unsigned EntryBlk = 0, LoopBlk = 1;
2903 
2904   ValueIDNum LiveInRsp = ValueIDNum(EntryBlk, 0, RspLoc);
2905   ValueIDNum LiveInRax = ValueIDNum(EntryBlk, 0, RaxLoc);
2906   ValueIDNum RspPHIInBlk1 = ValueIDNum(LoopBlk, 0, RspLoc);
2907   ValueIDNum RspDefInBlk1 = ValueIDNum(LoopBlk, 1, RspLoc);
2908   ValueIDNum RaxPHIInBlk1 = ValueIDNum(LoopBlk, 0, RaxLoc);
2909   DbgOpID LiveInRspID = addValueDbgOp(LiveInRsp);
2910   DbgOpID LiveInRaxID = addValueDbgOp(LiveInRax);
2911   DbgOpID RspPHIInBlk1ID = addValueDbgOp(RspPHIInBlk1);
2912   DbgOpID RspDefInBlk1ID = addValueDbgOp(RspDefInBlk1);
2913   DbgOpID RaxPHIInBlk1ID = addValueDbgOp(RaxPHIInBlk1);
2914 
2915   auto [MInLocs, MOutLocs] = allocValueTables(3, 2);
2916 
2917   initValueArray(MInLocs, 3, 2);
2918   initValueArray(MOutLocs, 3, 2);
2919 
2920   DebugVariable Var(FuncVariable, std::nullopt, nullptr);
2921   DebugVariableID VarID = LDV->getDVMap().insertDVID(Var, OutermostLoc);
2922   DbgValueProperties EmptyProps(EmptyExpr, false, false);
2923   DIExpression *TwoOpExpr =
2924       DIExpression::get(Ctx, {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_arg,
2925                               1, dwarf::DW_OP_plus});
2926   DbgValueProperties VariadicProps(TwoOpExpr, false, true);
2927 
2928   SmallSet<DebugVariableID, 4> AllVars;
2929   AllVars.insert(VarID);
2930 
2931   SmallPtrSet<MachineBasicBlock *, 4> AssignBlocks;
2932   AssignBlocks.insert(MBB0);
2933   AssignBlocks.insert(MBB1);
2934   AssignBlocks.insert(MBB2);
2935 
2936   SmallVector<VLocTracker, 3> VLocs;
2937   VLocs.resize(3, VLocTracker(LDV->getDVMap(), Overlaps, EmptyExpr));
2938 
2939   InstrRefBasedLDV::LiveInsT Output;
2940 
2941   // Start off with LiveInRsp in every location.
2942   for (unsigned int I = 0; I < 3; ++I) {
2943     MInLocs[I][0] = MInLocs[I][1] = LiveInRsp;
2944     MOutLocs[I][0] = MOutLocs[I][1] = LiveInRsp;
2945   }
2946 
2947   auto ClearOutputs = [&]() {
2948     for (auto &Elem : Output)
2949       Elem.clear();
2950   };
2951   Output.resize(3);
2952 
2953   // Easy starter: a dominating assign should propagate to all blocks.
2954   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
2955   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
2956                     MOutLocs, MInLocs, VLocs);
2957   EXPECT_EQ(Output[0].size(), 0ul);
2958   ASSERT_EQ(Output[1].size(), 1ul);
2959   ASSERT_EQ(Output[2].size(), 1ul);
2960   EXPECT_EQ(Output[1][0].second.Kind, DbgValue::Def);
2961   EXPECT_EQ(Output[1][0].second.getDbgOpID(0), LiveInRspID);
2962   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
2963   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), LiveInRspID);
2964   ClearOutputs();
2965   VLocs[0].Vars.clear();
2966   VLocs[1].Vars.clear();
2967 
2968   // A variadic assignment should behave the same.
2969   DbgOpID Locs0[] = {LiveInRspID, LiveInRaxID};
2970   VLocs[0].Vars.insert({VarID, DbgValue(Locs0, VariadicProps)});
2971   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, MOutLocs,
2972                     MInLocs, VLocs);
2973   EXPECT_EQ(Output[0].size(), 0ul);
2974   ASSERT_EQ(Output[1].size(), 1ul);
2975   ASSERT_EQ(Output[2].size(), 1ul);
2976   EXPECT_EQ(Output[1][0].second.Kind, DbgValue::Def);
2977   EXPECT_EQ(Output[1][0].second.getDbgOpID(0), LiveInRspID);
2978   EXPECT_EQ(Output[1][0].second.getDbgOpID(1), LiveInRaxID);
2979   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
2980   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), LiveInRspID);
2981   ClearOutputs();
2982   VLocs[0].Vars.clear();
2983   VLocs[1].Vars.clear();
2984 
2985   // Put an undef assignment in the loop. Should get no live-in value.
2986   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
2987   VLocs[1].Vars.insert({VarID, DbgValue(EmptyProps, DbgValue::Undef)});
2988   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
2989                     MOutLocs, MInLocs, VLocs);
2990   EXPECT_EQ(Output[0].size(), 0ul);
2991   EXPECT_EQ(Output[1].size(), 0ul);
2992   EXPECT_EQ(Output[2].size(), 0ul);
2993   ClearOutputs();
2994   VLocs[0].Vars.clear();
2995   VLocs[1].Vars.clear();
2996 
2997   // Assignment of the same value should naturally join.
2998   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
2999   VLocs[1].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
3000   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
3001                     MOutLocs, MInLocs, VLocs);
3002   EXPECT_EQ(Output[0].size(), 0ul);
3003   ASSERT_EQ(Output[1].size(), 1ul);
3004   ASSERT_EQ(Output[2].size(), 1ul);
3005   EXPECT_EQ(Output[1][0].second.Kind, DbgValue::Def);
3006   EXPECT_EQ(Output[1][0].second.getDbgOpID(0), LiveInRspID);
3007   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
3008   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), LiveInRspID);
3009   ClearOutputs();
3010   VLocs[0].Vars.clear();
3011   VLocs[1].Vars.clear();
3012 
3013   // Assignment of different values shouldn't join with no machine PHI vals.
3014   // Will be live-in to exit block as it's dominated.
3015   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
3016   VLocs[1].Vars.insert({VarID, DbgValue(LiveInRaxID, EmptyProps)});
3017   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
3018                     MOutLocs, MInLocs, VLocs);
3019   EXPECT_EQ(Output[0].size(), 0ul);
3020   EXPECT_EQ(Output[1].size(), 0ul);
3021   ASSERT_EQ(Output[2].size(), 1ul);
3022   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
3023   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), LiveInRaxID);
3024   ClearOutputs();
3025   VLocs[0].Vars.clear();
3026   VLocs[1].Vars.clear();
3027 
3028   // Install a completely unrelated PHI value, that we should not join on. Try
3029   // with unrelated assign in loop block again.
3030   MInLocs[1][0] = RspPHIInBlk1;
3031   MOutLocs[1][0] = RspDefInBlk1;
3032   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
3033   VLocs[1].Vars.insert({VarID, DbgValue(LiveInRaxID, EmptyProps)});
3034   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
3035                     MOutLocs, MInLocs, VLocs);
3036   EXPECT_EQ(Output[0].size(), 0ul);
3037   EXPECT_EQ(Output[1].size(), 0ul);
3038   ASSERT_EQ(Output[2].size(), 1ul);
3039   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
3040   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), LiveInRaxID);
3041   ClearOutputs();
3042   VLocs[0].Vars.clear();
3043   VLocs[1].Vars.clear();
3044 
3045   // Now, if we assign RspDefInBlk1 in the loop block, we should be able to
3046   // find the appropriate PHI.
3047   MInLocs[1][0] = RspPHIInBlk1;
3048   MOutLocs[1][0] = RspDefInBlk1;
3049   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
3050   VLocs[1].Vars.insert({VarID, DbgValue(RspDefInBlk1ID, EmptyProps)});
3051   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
3052                     MOutLocs, MInLocs, VLocs);
3053   EXPECT_EQ(Output[0].size(), 0ul);
3054   ASSERT_EQ(Output[1].size(), 1ul);
3055   ASSERT_EQ(Output[2].size(), 1ul);
3056   EXPECT_EQ(Output[1][0].second.Kind, DbgValue::Def);
3057   EXPECT_EQ(Output[1][0].second.getDbgOpID(0), RspPHIInBlk1ID);
3058   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
3059   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), RspDefInBlk1ID);
3060   ClearOutputs();
3061   VLocs[0].Vars.clear();
3062   VLocs[1].Vars.clear();
3063 
3064   // If the PHI happens in a different location, the live-in should happen
3065   // there.
3066   MInLocs[1][0] = LiveInRsp;
3067   MOutLocs[1][0] = LiveInRsp;
3068   MInLocs[1][1] = RaxPHIInBlk1;
3069   MOutLocs[1][1] = RspDefInBlk1;
3070   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
3071   VLocs[1].Vars.insert({VarID, DbgValue(RspDefInBlk1ID, EmptyProps)});
3072   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
3073                     MOutLocs, MInLocs, VLocs);
3074   EXPECT_EQ(Output[0].size(), 0ul);
3075   ASSERT_EQ(Output[1].size(), 1ul);
3076   ASSERT_EQ(Output[2].size(), 1ul);
3077   EXPECT_EQ(Output[1][0].second.Kind, DbgValue::Def);
3078   EXPECT_EQ(Output[1][0].second.getDbgOpID(0), RaxPHIInBlk1ID);
3079   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
3080   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), RspDefInBlk1ID);
3081   ClearOutputs();
3082   VLocs[0].Vars.clear();
3083   VLocs[1].Vars.clear();
3084 
3085   // The PHI happening in both places should be handled too. Exactly where
3086   // isn't important, but if the location picked changes, this test will let
3087   // you know.
3088   MInLocs[1][0] = RaxPHIInBlk1;
3089   MOutLocs[1][0] = RspDefInBlk1;
3090   MInLocs[1][1] = RaxPHIInBlk1;
3091   MOutLocs[1][1] = RspDefInBlk1;
3092   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
3093   VLocs[1].Vars.insert({VarID, DbgValue(RspDefInBlk1ID, EmptyProps)});
3094   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
3095                     MOutLocs, MInLocs, VLocs);
3096   EXPECT_EQ(Output[0].size(), 0ul);
3097   ASSERT_EQ(Output[1].size(), 1ul);
3098   ASSERT_EQ(Output[2].size(), 1ul);
3099   EXPECT_EQ(Output[1][0].second.Kind, DbgValue::Def);
3100   // Today, the first register is picked.
3101   EXPECT_EQ(Output[1][0].second.getDbgOpID(0), RspPHIInBlk1ID);
3102   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
3103   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), RspDefInBlk1ID);
3104   ClearOutputs();
3105   VLocs[0].Vars.clear();
3106   VLocs[1].Vars.clear();
3107 
3108   // If the loop block looked a bit like this:
3109   //    %0 = PHI %1, %2
3110   //    [...]
3111   //    DBG_VALUE %0
3112   // Then with instr-ref it becomes:
3113   //    DBG_PHI %0
3114   //    [...]
3115   //    DBG_INSTR_REF
3116   // And we would be feeding a machine PHI-value back around the loop. However:
3117   // this does not mean we can eliminate the variable value PHI and use the
3118   // variable value from the entry block: they are distinct values that must be
3119   // joined at some location by the control flow.
3120   // [This test input would never occur naturally, the machine-PHI would be
3121   //  eliminated]
3122   MInLocs[1][0] = RspPHIInBlk1;
3123   MOutLocs[1][0] = RspPHIInBlk1;
3124   MInLocs[1][1] = LiveInRax;
3125   MOutLocs[1][1] = LiveInRax;
3126   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
3127   VLocs[1].Vars.insert({VarID, DbgValue(RspPHIInBlk1ID, EmptyProps)});
3128   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
3129                     MOutLocs, MInLocs, VLocs);
3130   EXPECT_EQ(Output[0].size(), 0ul);
3131   ASSERT_EQ(Output[1].size(), 1ul);
3132   ASSERT_EQ(Output[2].size(), 1ul);
3133   EXPECT_EQ(Output[1][0].second.Kind, DbgValue::Def);
3134   EXPECT_EQ(Output[1][0].second.getDbgOpID(0), RspPHIInBlk1ID);
3135   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
3136   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), RspPHIInBlk1ID);
3137   ClearOutputs();
3138   VLocs[0].Vars.clear();
3139   VLocs[1].Vars.clear();
3140 
3141   // Test that we can eliminate PHIs. A PHI will be placed at the loop head
3142   // because there's a def in it.
3143   MInLocs[1][0] = LiveInRsp;
3144   MOutLocs[1][0] = LiveInRsp;
3145   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
3146   VLocs[1].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
3147   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
3148                     MOutLocs, MInLocs, VLocs);
3149   EXPECT_EQ(Output[0].size(), 0ul);
3150   ASSERT_EQ(Output[1].size(), 1ul);
3151   ASSERT_EQ(Output[2].size(), 1ul);
3152   EXPECT_EQ(Output[1][0].second.Kind, DbgValue::Def);
3153   EXPECT_EQ(Output[1][0].second.getDbgOpID(0), LiveInRspID);
3154   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
3155   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), LiveInRspID);
3156   ClearOutputs();
3157   VLocs[0].Vars.clear();
3158   VLocs[1].Vars.clear();
3159 }
3160 
3161 // test phi elimination with the nested situation
3162 TEST_F(InstrRefLDVTest, VLocNestedLoop) {
3163   //    entry
3164   //     |
3165   //    loop1
3166   //     ^\
3167   //     | \    /-\
3168   //     |  loop2  |
3169   //     |  /   \-/
3170   //     ^ /
3171   //     join
3172   //     |
3173   //     ret
3174   setupNestedLoops();
3175 
3176   ASSERT_TRUE(MTracker->getNumLocs() == 1);
3177   LocIdx RspLoc(0);
3178   Register RAX = getRegByName("RAX");
3179   LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX);
3180 
3181   unsigned EntryBlk = 0, Loop1Blk = 1, Loop2Blk = 2;
3182 
3183   ValueIDNum LiveInRsp = ValueIDNum(EntryBlk, 0, RspLoc);
3184   ValueIDNum LiveInRax = ValueIDNum(EntryBlk, 0, RaxLoc);
3185   ValueIDNum RspPHIInBlk1 = ValueIDNum(Loop1Blk, 0, RspLoc);
3186   ValueIDNum RspPHIInBlk2 = ValueIDNum(Loop2Blk, 0, RspLoc);
3187   ValueIDNum RspDefInBlk2 = ValueIDNum(Loop2Blk, 1, RspLoc);
3188   DbgOpID LiveInRspID = addValueDbgOp(LiveInRsp);
3189   DbgOpID LiveInRaxID = addValueDbgOp(LiveInRax);
3190   DbgOpID RspPHIInBlk1ID = addValueDbgOp(RspPHIInBlk1);
3191   DbgOpID RspPHIInBlk2ID = addValueDbgOp(RspPHIInBlk2);
3192   DbgOpID RspDefInBlk2ID = addValueDbgOp(RspDefInBlk2);
3193 
3194   auto [MInLocs, MOutLocs] = allocValueTables(5, 2);
3195 
3196   initValueArray(MInLocs, 5, 2);
3197   initValueArray(MOutLocs, 5, 2);
3198 
3199   DebugVariable Var(FuncVariable, std::nullopt, nullptr);
3200   DebugVariableID VarID = LDV->getDVMap().insertDVID(Var, OutermostLoc);
3201   DbgValueProperties EmptyProps(EmptyExpr, false, false);
3202 
3203   SmallSet<DebugVariableID, 4> AllVars;
3204   AllVars.insert(VarID);
3205 
3206   SmallPtrSet<MachineBasicBlock *, 5> AssignBlocks;
3207   AssignBlocks.insert(MBB0);
3208   AssignBlocks.insert(MBB1);
3209   AssignBlocks.insert(MBB2);
3210   AssignBlocks.insert(MBB3);
3211   AssignBlocks.insert(MBB4);
3212 
3213   SmallVector<VLocTracker, 5> VLocs;
3214   VLocs.resize(5, VLocTracker(LDV->getDVMap(), Overlaps, EmptyExpr));
3215 
3216   InstrRefBasedLDV::LiveInsT Output;
3217 
3218   // Start off with LiveInRsp in every location.
3219   for (unsigned int I = 0; I < 5; ++I) {
3220     MInLocs[I][0] = MInLocs[I][1] = LiveInRsp;
3221     MOutLocs[I][0] = MOutLocs[I][1] = LiveInRsp;
3222   }
3223 
3224   auto ClearOutputs = [&]() {
3225     for (auto &Elem : Output)
3226       Elem.clear();
3227   };
3228   Output.resize(5);
3229 
3230   // A dominating assign should propagate to all blocks.
3231   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
3232   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
3233                     MOutLocs, MInLocs, VLocs);
3234   EXPECT_EQ(Output[0].size(), 0ul);
3235   ASSERT_EQ(Output[1].size(), 1ul);
3236   ASSERT_EQ(Output[2].size(), 1ul);
3237   ASSERT_EQ(Output[3].size(), 1ul);
3238   ASSERT_EQ(Output[4].size(), 1ul);
3239   EXPECT_EQ(Output[1][0].second.Kind, DbgValue::Def);
3240   EXPECT_EQ(Output[1][0].second.getDbgOpID(0), LiveInRspID);
3241   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
3242   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), LiveInRspID);
3243   EXPECT_EQ(Output[3][0].second.Kind, DbgValue::Def);
3244   EXPECT_EQ(Output[3][0].second.getDbgOpID(0), LiveInRspID);
3245   EXPECT_EQ(Output[4][0].second.Kind, DbgValue::Def);
3246   EXPECT_EQ(Output[4][0].second.getDbgOpID(0), LiveInRspID);
3247   ClearOutputs();
3248   VLocs[0].Vars.clear();
3249 
3250   // Test that an assign in the inner loop causes unresolved PHIs at the heads
3251   // of both loops, and no output location. Dominated blocks do get values.
3252   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
3253   VLocs[2].Vars.insert({VarID, DbgValue(LiveInRaxID, EmptyProps)});
3254   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
3255                     MOutLocs, MInLocs, VLocs);
3256   EXPECT_EQ(Output[0].size(), 0ul);
3257   EXPECT_EQ(Output[1].size(), 0ul);
3258   EXPECT_EQ(Output[2].size(), 0ul);
3259   ASSERT_EQ(Output[3].size(), 1ul);
3260   ASSERT_EQ(Output[4].size(), 1ul);
3261   EXPECT_EQ(Output[3][0].second.Kind, DbgValue::Def);
3262   EXPECT_EQ(Output[3][0].second.getDbgOpID(0), LiveInRaxID);
3263   EXPECT_EQ(Output[4][0].second.Kind, DbgValue::Def);
3264   EXPECT_EQ(Output[4][0].second.getDbgOpID(0), LiveInRaxID);
3265   ClearOutputs();
3266   VLocs[0].Vars.clear();
3267   VLocs[2].Vars.clear();
3268 
3269   // Same test, but with no assignment in block 0. We should still get values
3270   // in dominated blocks.
3271   VLocs[2].Vars.insert({VarID, DbgValue(LiveInRaxID, EmptyProps)});
3272   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
3273                     MOutLocs, MInLocs, VLocs);
3274   EXPECT_EQ(Output[0].size(), 0ul);
3275   EXPECT_EQ(Output[1].size(), 0ul);
3276   EXPECT_EQ(Output[2].size(), 0ul);
3277   ASSERT_EQ(Output[3].size(), 1ul);
3278   ASSERT_EQ(Output[4].size(), 1ul);
3279   EXPECT_EQ(Output[3][0].second.Kind, DbgValue::Def);
3280   EXPECT_EQ(Output[3][0].second.getDbgOpID(0), LiveInRaxID);
3281   EXPECT_EQ(Output[4][0].second.Kind, DbgValue::Def);
3282   EXPECT_EQ(Output[4][0].second.getDbgOpID(0), LiveInRaxID);
3283   ClearOutputs();
3284   VLocs[2].Vars.clear();
3285 
3286   // Similarly, assignments in the outer loop gives location to dominated
3287   // blocks, but no PHI locations are found at the outer loop head.
3288   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
3289   VLocs[3].Vars.insert({VarID, DbgValue(LiveInRaxID, EmptyProps)});
3290   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
3291                     MOutLocs, MInLocs, VLocs);
3292   EXPECT_EQ(Output[0].size(), 0ul);
3293   EXPECT_EQ(Output[1].size(), 0ul);
3294   EXPECT_EQ(Output[2].size(), 0ul);
3295   EXPECT_EQ(Output[3].size(), 0ul);
3296   ASSERT_EQ(Output[4].size(), 1ul);
3297   EXPECT_EQ(Output[4][0].second.Kind, DbgValue::Def);
3298   EXPECT_EQ(Output[4][0].second.getDbgOpID(0), LiveInRaxID);
3299   ClearOutputs();
3300   VLocs[0].Vars.clear();
3301   VLocs[3].Vars.clear();
3302 
3303   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
3304   VLocs[1].Vars.insert({VarID, DbgValue(LiveInRaxID, EmptyProps)});
3305   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
3306                     MOutLocs, MInLocs, VLocs);
3307   EXPECT_EQ(Output[0].size(), 0ul);
3308   EXPECT_EQ(Output[1].size(), 0ul);
3309   ASSERT_EQ(Output[2].size(), 1ul);
3310   ASSERT_EQ(Output[3].size(), 1ul);
3311   ASSERT_EQ(Output[4].size(), 1ul);
3312   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
3313   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), LiveInRaxID);
3314   EXPECT_EQ(Output[3][0].second.Kind, DbgValue::Def);
3315   EXPECT_EQ(Output[3][0].second.getDbgOpID(0), LiveInRaxID);
3316   EXPECT_EQ(Output[4][0].second.Kind, DbgValue::Def);
3317   EXPECT_EQ(Output[4][0].second.getDbgOpID(0), LiveInRaxID);
3318   ClearOutputs();
3319   VLocs[0].Vars.clear();
3320   VLocs[1].Vars.clear();
3321 
3322   // With an assignment of the same value in the inner loop, we should work out
3323   // that all PHIs can be eliminated and the same value is live-through the
3324   // whole function.
3325   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
3326   VLocs[2].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
3327   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
3328                     MOutLocs, MInLocs, VLocs);
3329   EXPECT_EQ(Output[0].size(), 0ul);
3330   EXPECT_EQ(Output[1].size(), 1ul);
3331   EXPECT_EQ(Output[2].size(), 1ul);
3332   ASSERT_EQ(Output[3].size(), 1ul);
3333   ASSERT_EQ(Output[4].size(), 1ul);
3334   EXPECT_EQ(Output[1][0].second.Kind, DbgValue::Def);
3335   EXPECT_EQ(Output[1][0].second.getDbgOpID(0), LiveInRspID);
3336   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
3337   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), LiveInRspID);
3338   EXPECT_EQ(Output[3][0].second.Kind, DbgValue::Def);
3339   EXPECT_EQ(Output[3][0].second.getDbgOpID(0), LiveInRspID);
3340   EXPECT_EQ(Output[4][0].second.Kind, DbgValue::Def);
3341   EXPECT_EQ(Output[4][0].second.getDbgOpID(0), LiveInRspID);
3342   ClearOutputs();
3343   VLocs[0].Vars.clear();
3344   VLocs[2].Vars.clear();
3345 
3346   // If we have an assignment in the inner loop, and a PHI for it at the inner
3347   // loop head, we could find a live-in location for the inner loop. But because
3348   // the outer loop has no PHI, we can't find a variable value for outer loop
3349   // head, so can't have a live-in value for the inner loop head.
3350   MInLocs[2][0] = RspPHIInBlk2;
3351   MOutLocs[2][0] = LiveInRax;
3352   // NB: all other machine locations are LiveInRsp, disallowing a PHI in block
3353   // one. Even though RspPHIInBlk2 isn't available later in the function, we
3354   // should still produce a live-in value. The fact it's unavailable is a
3355   // different concern.
3356   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
3357   VLocs[2].Vars.insert({VarID, DbgValue(LiveInRaxID, EmptyProps)});
3358   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
3359                     MOutLocs, MInLocs, VLocs);
3360   EXPECT_EQ(Output[0].size(), 0ul);
3361   EXPECT_EQ(Output[1].size(), 0ul);
3362   EXPECT_EQ(Output[2].size(), 0ul);
3363   ASSERT_EQ(Output[3].size(), 1ul);
3364   ASSERT_EQ(Output[4].size(), 1ul);
3365   EXPECT_EQ(Output[3][0].second.Kind, DbgValue::Def);
3366   EXPECT_EQ(Output[3][0].second.getDbgOpID(0), LiveInRaxID);
3367   EXPECT_EQ(Output[4][0].second.Kind, DbgValue::Def);
3368   EXPECT_EQ(Output[4][0].second.getDbgOpID(0), LiveInRaxID);
3369   ClearOutputs();
3370   VLocs[0].Vars.clear();
3371   VLocs[2].Vars.clear();
3372 
3373   // Have an assignment in inner loop that can have a PHI resolved; and add a
3374   // machine value PHI to the outer loop head, so that we can find a location
3375   // all the way through the function.
3376   MInLocs[1][0] = RspPHIInBlk1;
3377   MOutLocs[1][0] = RspPHIInBlk1;
3378   MInLocs[2][0] = RspPHIInBlk2;
3379   MOutLocs[2][0] = RspDefInBlk2;
3380   MInLocs[3][0] = RspDefInBlk2;
3381   MOutLocs[3][0] = RspDefInBlk2;
3382   VLocs[0].Vars.insert({VarID, DbgValue(LiveInRspID, EmptyProps)});
3383   VLocs[2].Vars.insert({VarID, DbgValue(RspDefInBlk2ID, EmptyProps)});
3384   buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output,
3385                     MOutLocs, MInLocs, VLocs);
3386   EXPECT_EQ(Output[0].size(), 0ul);
3387   ASSERT_EQ(Output[1].size(), 1ul);
3388   ASSERT_EQ(Output[2].size(), 1ul);
3389   ASSERT_EQ(Output[3].size(), 1ul);
3390   ASSERT_EQ(Output[4].size(), 1ul);
3391   EXPECT_EQ(Output[1][0].second.Kind, DbgValue::Def);
3392   EXPECT_EQ(Output[1][0].second.getDbgOpID(0), RspPHIInBlk1ID);
3393   EXPECT_EQ(Output[2][0].second.Kind, DbgValue::Def);
3394   EXPECT_EQ(Output[2][0].second.getDbgOpID(0), RspPHIInBlk2ID);
3395   EXPECT_EQ(Output[3][0].second.Kind, DbgValue::Def);
3396   EXPECT_EQ(Output[3][0].second.getDbgOpID(0), RspDefInBlk2ID);
3397   EXPECT_EQ(Output[4][0].second.Kind, DbgValue::Def);
3398   EXPECT_EQ(Output[4][0].second.getDbgOpID(0), RspDefInBlk2ID);
3399   ClearOutputs();
3400   VLocs[0].Vars.clear();
3401   VLocs[2].Vars.clear();
3402 }
3403