blob: 835d3f91c66e3a47d41ea0bd99f027ed5ae75179 [file] [log] [blame]
Matthias Braun3199c4e2016-05-02 23:05:48 +00001#include "llvm/ADT/STLExtras.h"
Matthias Braunf8422972017-12-13 02:51:04 +00002#include "llvm/CodeGen/LiveIntervals.h"
Matthias Braun3199c4e2016-05-02 23:05:48 +00003#include "llvm/CodeGen/MIRParser/MIRParser.h"
4#include "llvm/CodeGen/MachineFunction.h"
Matthias Braun7938eee2016-05-10 03:03:55 +00005#include "llvm/CodeGen/MachineModuleInfo.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +00006#include "llvm/CodeGen/TargetRegisterInfo.h"
Chandler Carruth9a67b072017-06-06 11:06:56 +00007#include "llvm/IR/LegacyPassManager.h"
Heejin Ahn3306fe12019-11-13 18:19:54 -08008#include "llvm/InitializePasses.h"
Matthias Braun3199c4e2016-05-02 23:05:48 +00009#include "llvm/Support/MemoryBuffer.h"
10#include "llvm/Support/SourceMgr.h"
11#include "llvm/Support/TargetRegistry.h"
12#include "llvm/Support/TargetSelect.h"
13#include "llvm/Target/TargetMachine.h"
14#include "llvm/Target/TargetOptions.h"
Chandler Carruth9a67b072017-06-06 11:06:56 +000015#include "gtest/gtest.h"
NAKAMURA Takumic1857d12016-02-18 07:37:17 +000016
Matthias Braun3199c4e2016-05-02 23:05:48 +000017using namespace llvm;
18
19namespace llvm {
20 void initializeTestPassPass(PassRegistry &);
21}
22
23namespace {
24
25void initLLVM() {
26 InitializeAllTargets();
27 InitializeAllTargetMCs();
28 InitializeAllAsmPrinters();
29 InitializeAllAsmParsers();
30
31 PassRegistry *Registry = PassRegistry::getPassRegistry();
32 initializeCore(*Registry);
33 initializeCodeGen(*Registry);
34}
35
36/// Create a TargetMachine. As we lack a dedicated always available target for
Matthias Braun3865b1d2016-07-26 03:57:45 +000037/// unittests, we go for "AMDGPU" to be able to test normal and subregister
38/// liveranges.
Matthias Braun3d849f62018-11-05 23:49:13 +000039std::unique_ptr<LLVMTargetMachine> createTargetMachine() {
Matthias Braun3865b1d2016-07-26 03:57:45 +000040 Triple TargetTriple("amdgcn--");
Matthias Braun3199c4e2016-05-02 23:05:48 +000041 std::string Error;
42 const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
43 if (!T)
44 return nullptr;
45
46 TargetOptions Options;
Matthias Braun3d849f62018-11-05 23:49:13 +000047 return std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine*>(
48 T->createTargetMachine("AMDGPU", "", "", Options, None, None,
49 CodeGenOpt::Aggressive)));
Matthias Braun3199c4e2016-05-02 23:05:48 +000050}
51
52std::unique_ptr<Module> parseMIR(LLVMContext &Context,
53 legacy::PassManagerBase &PM, std::unique_ptr<MIRParser> &MIR,
Matthias Braun3d849f62018-11-05 23:49:13 +000054 const LLVMTargetMachine &TM, StringRef MIRCode, const char *FuncName) {
Matthias Braun3199c4e2016-05-02 23:05:48 +000055 SMDiagnostic Diagnostic;
56 std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);
57 MIR = createMIRParser(std::move(MBuffer), Context);
58 if (!MIR)
59 return nullptr;
60
Matthias Braun7bda1952017-06-06 00:44:35 +000061 std::unique_ptr<Module> M = MIR->parseIRModule();
Matthias Braun3199c4e2016-05-02 23:05:48 +000062 if (!M)
63 return nullptr;
64
65 M->setDataLayout(TM.createDataLayout());
66
Yuanfang Chencc382cf2019-09-30 17:54:50 +000067 MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(&TM);
68 if (MIR->parseMachineFunctions(*M, MMIWP->getMMI()))
Matthias Braun7bda1952017-06-06 00:44:35 +000069 return nullptr;
Yuanfang Chencc382cf2019-09-30 17:54:50 +000070 PM.add(MMIWP);
Matthias Braun3199c4e2016-05-02 23:05:48 +000071
72 return M;
73}
74
75typedef std::function<void(MachineFunction&,LiveIntervals&)> LiveIntervalTest;
76
77struct TestPass : public MachineFunctionPass {
78 static char ID;
79 TestPass() : MachineFunctionPass(ID) {
80 // We should never call this but always use PM.add(new TestPass(...))
81 abort();
82 }
83 TestPass(LiveIntervalTest T) : MachineFunctionPass(ID), T(T) {
84 initializeTestPassPass(*PassRegistry::getPassRegistry());
85 }
86
87 bool runOnMachineFunction(MachineFunction &MF) override {
88 LiveIntervals &LIS = getAnalysis<LiveIntervals>();
89 T(MF, LIS);
90 EXPECT_TRUE(MF.verify(this));
91 return true;
92 }
93
94 void getAnalysisUsage(AnalysisUsage &AU) const override {
95 AU.setPreservesAll();
96 AU.addRequired<LiveIntervals>();
97 AU.addPreserved<LiveIntervals>();
98 MachineFunctionPass::getAnalysisUsage(AU);
99 }
100private:
101 LiveIntervalTest T;
102};
103
Matthias Braun3865b1d2016-07-26 03:57:45 +0000104static MachineInstr &getMI(MachineFunction &MF, unsigned At,
105 unsigned BlockNum) {
106 MachineBasicBlock &MBB = *MF.getBlockNumbered(BlockNum);
107
108 unsigned I = 0;
109 for (MachineInstr &MI : MBB) {
110 if (I == At)
111 return MI;
112 ++I;
113 }
114 llvm_unreachable("Instruction not found");
115}
116
Matthias Braun3199c4e2016-05-02 23:05:48 +0000117/**
118 * Move instruction number \p From in front of instruction number \p To and
119 * update affected liveness intervals with LiveIntervalAnalysis::handleMove().
120 */
121static void testHandleMove(MachineFunction &MF, LiveIntervals &LIS,
Matthias Braunfc4c8a12016-05-24 21:54:01 +0000122 unsigned From, unsigned To, unsigned BlockNum = 0) {
Matthias Braun3865b1d2016-07-26 03:57:45 +0000123 MachineInstr &FromInstr = getMI(MF, From, BlockNum);
124 MachineInstr &ToInstr = getMI(MF, To, BlockNum);
Matthias Braun3199c4e2016-05-02 23:05:48 +0000125
Matthias Braun3865b1d2016-07-26 03:57:45 +0000126 MachineBasicBlock &MBB = *FromInstr.getParent();
127 MBB.splice(ToInstr.getIterator(), &MBB, FromInstr.getIterator());
128 LIS.handleMove(FromInstr, true);
Matthias Braun3199c4e2016-05-02 23:05:48 +0000129}
130
131static void liveIntervalTest(StringRef MIRFunc, LiveIntervalTest T) {
132 LLVMContext Context;
Matthias Braun3d849f62018-11-05 23:49:13 +0000133 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
Matthias Braun3199c4e2016-05-02 23:05:48 +0000134 // This test is designed for the X86 backend; stop if it is not available.
135 if (!TM)
136 return;
137
138 legacy::PassManager PM;
139
140 SmallString<160> S;
Matthias Braun1cba1402017-02-23 01:09:01 +0000141 StringRef MIRString = (Twine(R"MIR(
142---
143...
144name: func
145registers:
146 - { id: 0, class: sreg_64 }
147body: |
148 bb.0:
149)MIR") + Twine(MIRFunc) + Twine("...\n")).toNullTerminatedStringRef(S);
Matthias Braun3199c4e2016-05-02 23:05:48 +0000150 std::unique_ptr<MIRParser> MIR;
151 std::unique_ptr<Module> M = parseMIR(Context, PM, MIR, *TM, MIRString,
152 "func");
Matthias Braun531f3a92017-06-15 22:50:57 +0000153 ASSERT_TRUE(M);
Matthias Braun3199c4e2016-05-02 23:05:48 +0000154
155 PM.add(new TestPass(T));
156
157 PM.run(*M);
158}
159
160} // End of anonymous namespace.
161
162char TestPass::ID = 0;
163INITIALIZE_PASS(TestPass, "testpass", "testpass", false, false)
164
165TEST(LiveIntervalTest, MoveUpDef) {
166 // Value defined.
Matthias Braun1cba1402017-02-23 01:09:01 +0000167 liveIntervalTest(R"MIR(
168 S_NOP 0
169 S_NOP 0
170 early-clobber %0 = IMPLICIT_DEF
171 S_NOP 0, implicit %0
172)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000173 testHandleMove(MF, LIS, 2, 1);
174 });
175}
176
177TEST(LiveIntervalTest, MoveUpRedef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000178 liveIntervalTest(R"MIR(
179 %0 = IMPLICIT_DEF
180 S_NOP 0
181 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
182 S_NOP 0, implicit %0
183)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000184 testHandleMove(MF, LIS, 2, 1);
185 });
186}
187
188TEST(LiveIntervalTest, MoveUpEarlyDef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000189 liveIntervalTest(R"MIR(
190 S_NOP 0
191 S_NOP 0
192 early-clobber %0 = IMPLICIT_DEF
193 S_NOP 0, implicit %0
194)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000195 testHandleMove(MF, LIS, 2, 1);
196 });
197}
198
199TEST(LiveIntervalTest, MoveUpEarlyRedef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000200 liveIntervalTest(R"MIR(
201 %0 = IMPLICIT_DEF
202 S_NOP 0
203 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
204 S_NOP 0, implicit %0
205)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000206 testHandleMove(MF, LIS, 2, 1);
207 });
208}
209
210TEST(LiveIntervalTest, MoveUpKill) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000211 liveIntervalTest(R"MIR(
212 %0 = IMPLICIT_DEF
213 S_NOP 0
214 S_NOP 0, implicit %0
215)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000216 testHandleMove(MF, LIS, 2, 1);
217 });
218}
219
220TEST(LiveIntervalTest, MoveUpKillFollowing) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000221 liveIntervalTest(R"MIR(
222 %0 = IMPLICIT_DEF
223 S_NOP 0
224 S_NOP 0, implicit %0
225 S_NOP 0, implicit %0
226)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000227 testHandleMove(MF, LIS, 2, 1);
228 });
229}
230
231// TODO: Construct a situation where we have intervals following a hole
232// while still having connected components.
233
234TEST(LiveIntervalTest, MoveDownDef) {
235 // Value defined.
Matthias Braun1cba1402017-02-23 01:09:01 +0000236 liveIntervalTest(R"MIR(
237 S_NOP 0
238 early-clobber %0 = IMPLICIT_DEF
239 S_NOP 0
240 S_NOP 0, implicit %0
241)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000242 testHandleMove(MF, LIS, 1, 2);
243 });
244}
245
246TEST(LiveIntervalTest, MoveDownRedef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000247 liveIntervalTest(R"MIR(
248 %0 = IMPLICIT_DEF
249 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
250 S_NOP 0
251 S_NOP 0, implicit %0
252)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000253 testHandleMove(MF, LIS, 1, 2);
254 });
255}
256
257TEST(LiveIntervalTest, MoveDownEarlyDef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000258 liveIntervalTest(R"MIR(
259 S_NOP 0
260 early-clobber %0 = IMPLICIT_DEF
261 S_NOP 0
262 S_NOP 0, implicit %0
263)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000264 testHandleMove(MF, LIS, 1, 2);
265 });
266}
267
268TEST(LiveIntervalTest, MoveDownEarlyRedef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000269 liveIntervalTest(R"MIR(
270 %0 = IMPLICIT_DEF
271 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
272 S_NOP 0
273 S_NOP 0, implicit %0
274)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000275 testHandleMove(MF, LIS, 1, 2);
276 });
277}
278
279TEST(LiveIntervalTest, MoveDownKill) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000280 liveIntervalTest(R"MIR(
281 %0 = IMPLICIT_DEF
282 S_NOP 0, implicit %0
283 S_NOP 0
284)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000285 testHandleMove(MF, LIS, 1, 2);
286 });
287}
288
289TEST(LiveIntervalTest, MoveDownKillFollowing) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000290 liveIntervalTest(R"MIR(
291 %0 = IMPLICIT_DEF
292 S_NOP 0
293 S_NOP 0, implicit %0
294 S_NOP 0, implicit %0
295)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000296 testHandleMove(MF, LIS, 1, 2);
297 });
298}
299
Matthias Braun71474e82016-05-06 21:47:41 +0000300TEST(LiveIntervalTest, MoveUndefUse) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000301 liveIntervalTest(R"MIR(
302 %0 = IMPLICIT_DEF
303 S_NOP 0, implicit undef %0
304 S_NOP 0, implicit %0
305 S_NOP 0
306)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun71474e82016-05-06 21:47:41 +0000307 testHandleMove(MF, LIS, 1, 3);
308 });
309}
310
Matthias Braunfc4c8a12016-05-24 21:54:01 +0000311TEST(LiveIntervalTest, MoveUpValNos) {
312 // handleMoveUp() had a bug where it would reuse the value number of the
Matt Arsenaultdf3af002019-09-26 15:20:16 +0000313 // destination segment, even though we have no guarantee that this valno
314 // wasn't used in other segments.
Matthias Braun1cba1402017-02-23 01:09:01 +0000315 liveIntervalTest(R"MIR(
316 successors: %bb.1, %bb.2
317 %0 = IMPLICIT_DEF
Puyan Lotfi43e94b12018-01-31 22:04:26 +0000318 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
Matthias Braun1cba1402017-02-23 01:09:01 +0000319 S_BRANCH %bb.1
320 bb.2:
321 S_NOP 0, implicit %0
322 bb.1:
323 successors: %bb.2
324 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
325 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
326 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
327 S_BRANCH %bb.2
328)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braunfc4c8a12016-05-24 21:54:01 +0000329 testHandleMove(MF, LIS, 2, 0, 2);
330 });
331}
332
Matthias Braun959a8c92016-06-11 00:31:28 +0000333TEST(LiveIntervalTest, MoveOverUndefUse0) {
334 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
Matthias Braun1cba1402017-02-23 01:09:01 +0000335 liveIntervalTest(R"MIR(
336 %0 = IMPLICIT_DEF
337 S_NOP 0
338 S_NOP 0, implicit undef %0
339 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
340)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun959a8c92016-06-11 00:31:28 +0000341 testHandleMove(MF, LIS, 3, 1);
342 });
343}
344
345TEST(LiveIntervalTest, MoveOverUndefUse1) {
346 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
Matthias Braun1cba1402017-02-23 01:09:01 +0000347 liveIntervalTest(R"MIR(
Puyan Lotfi43e94b12018-01-31 22:04:26 +0000348 $sgpr0 = IMPLICIT_DEF
Matthias Braun1cba1402017-02-23 01:09:01 +0000349 S_NOP 0
Puyan Lotfi43e94b12018-01-31 22:04:26 +0000350 S_NOP 0, implicit undef $sgpr0
351 $sgpr0 = IMPLICIT_DEF implicit $sgpr0(tied-def 0)
Matthias Braun1cba1402017-02-23 01:09:01 +0000352)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun959a8c92016-06-11 00:31:28 +0000353 testHandleMove(MF, LIS, 3, 1);
354 });
355}
356
Matthias Braun3865b1d2016-07-26 03:57:45 +0000357TEST(LiveIntervalTest, SubRegMoveDown) {
358 // Subregister ranges can have holes inside a basic block. Check for a
359 // movement of the form 32->150 in a liverange [16, 32) [100,200).
Matthias Braun1cba1402017-02-23 01:09:01 +0000360 liveIntervalTest(R"MIR(
361 successors: %bb.1, %bb.2
362 %0 = IMPLICIT_DEF
Puyan Lotfi43e94b12018-01-31 22:04:26 +0000363 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
Matthias Braun1cba1402017-02-23 01:09:01 +0000364 S_BRANCH %bb.1
365 bb.2:
366 successors: %bb.1
367 S_NOP 0, implicit %0.sub0
368 S_NOP 0, implicit %0.sub1
369 S_NOP 0
370 undef %0.sub0 = IMPLICIT_DEF
371 %0.sub1 = IMPLICIT_DEF
372 bb.1:
373 S_NOP 0, implicit %0
374)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3865b1d2016-07-26 03:57:45 +0000375 // Scheduler behaviour: Clear def,read-undef flag and move.
376 MachineInstr &MI = getMI(MF, 3, /*BlockNum=*/1);
377 MI.getOperand(0).setIsUndef(false);
378 testHandleMove(MF, LIS, 1, 4, /*BlockNum=*/1);
379 });
380}
381
Stanislav Mekhanoshinb546174b2017-03-11 00:14:52 +0000382TEST(LiveIntervalTest, SubRegMoveUp) {
383 // handleMoveUp had a bug not updating valno of segment incoming to bb.2
384 // after swapping subreg definitions.
385 liveIntervalTest(R"MIR(
386 successors: %bb.1, %bb.2
387 undef %0.sub0 = IMPLICIT_DEF
388 %0.sub1 = IMPLICIT_DEF
Puyan Lotfi43e94b12018-01-31 22:04:26 +0000389 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
Stanislav Mekhanoshinb546174b2017-03-11 00:14:52 +0000390 S_BRANCH %bb.1
391 bb.1:
392 S_NOP 0, implicit %0.sub1
393 bb.2:
394 S_NOP 0, implicit %0.sub1
395)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
396 testHandleMove(MF, LIS, 1, 0);
397 });
398}
399
Tim Renouff40707a2018-02-26 14:42:13 +0000400TEST(LiveIntervalTest, DeadSubRegMoveUp) {
401 // handleMoveUp had a bug where moving a dead subreg def into the middle of
402 // an earlier segment resulted in an invalid live range.
403 liveIntervalTest(R"MIR(
404 undef %125.sub0:vreg_128 = V_MOV_B32_e32 0, implicit $exec
405 %125.sub1:vreg_128 = COPY %125.sub0
406 %125.sub2:vreg_128 = COPY %125.sub0
407 undef %51.sub0:vreg_128 = V_MOV_B32_e32 898625526, implicit $exec
408 %51.sub1:vreg_128 = COPY %51.sub0
409 %51.sub2:vreg_128 = COPY %51.sub0
410 %52:vgpr_32 = V_MOV_B32_e32 986714345, implicit $exec
411 %54:vgpr_32 = V_MOV_B32_e32 1742342378, implicit $exec
412 %57:vgpr_32 = V_MOV_B32_e32 3168768712, implicit $exec
413 %59:vgpr_32 = V_MOV_B32_e32 1039972644, implicit $exec
414 %60:vgpr_32 = V_MAD_F32 0, %52, 0, undef %61:vgpr_32, 0, %59, 0, 0, implicit $exec
415 %63:vgpr_32 = V_ADD_F32_e32 %51.sub3, undef %64:vgpr_32, implicit $exec
416 dead %66:vgpr_32 = V_MAD_F32 0, %60, 0, undef %67:vgpr_32, 0, %125.sub2, 0, 0, implicit $exec
417 undef %124.sub1:vreg_128 = V_MAD_F32 0, %57, 0, undef %70:vgpr_32, 0, %125.sub1, 0, 0, implicit $exec
418 %124.sub0:vreg_128 = V_MAD_F32 0, %54, 0, undef %73:vgpr_32, 0, %125.sub0, 0, 0, implicit $exec
419 dead undef %125.sub3:vreg_128 = V_MAC_F32_e32 %63, undef %76:vgpr_32, %125.sub3, implicit $exec
420)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
421 testHandleMove(MF, LIS, 15, 12);
422 });
423}
424
Matt Arsenaultd4274f02019-10-18 23:24:25 +0000425TEST(LiveIntervalTest, TestMoveSubRegDefAcrossUseDef) {
426 liveIntervalTest(R"MIR(
427 %1:vreg_64 = IMPLICIT_DEF
428
429 bb.1:
430 %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec
431 %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec
432 undef %1.sub0:vreg_64 = V_ADD_U32_e32 %2, %2, implicit $exec
433 %1.sub1:vreg_64 = COPY %2
434 S_NOP 0, implicit %1.sub1
435 S_BRANCH %bb.1
436
437)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
438 MachineInstr &UndefSubregDef = getMI(MF, 2, 1);
439 // The scheduler clears undef from subregister defs before moving
440 UndefSubregDef.getOperand(0).setIsUndef(false);
441 testHandleMove(MF, LIS, 3, 1, 1);
442 });
443}
444
445TEST(LiveIntervalTest, TestMoveSubRegDefAcrossUseDefMulti) {
446 liveIntervalTest(R"MIR(
447 %1:vreg_96 = IMPLICIT_DEF
448
449 bb.1:
450 %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec
451 %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec
452 undef %1.sub0:vreg_96 = V_ADD_U32_e32 %2, %2, implicit $exec
453 %1.sub1:vreg_96 = COPY %2
454 %1.sub2:vreg_96 = COPY %2
455 S_NOP 0, implicit %1.sub1, implicit %1.sub2
456 S_BRANCH %bb.1
457
458)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
459 MachineInstr &UndefSubregDef = getMI(MF, 2, 1);
460 // The scheduler clears undef from subregister defs before moving
461 UndefSubregDef.getOperand(0).setIsUndef(false);
462 testHandleMove(MF, LIS, 4, 1, 1);
463 });
464}
Matthias Braun3199c4e2016-05-02 23:05:48 +0000465int main(int argc, char **argv) {
466 ::testing::InitGoogleTest(&argc, argv);
467 initLLVM();
468 return RUN_ALL_TESTS();
NAKAMURA Takumic1857d12016-02-18 07:37:17 +0000469}