1 #include "llvm/ADT/STLExtras.h"
2 #include "llvm/CodeGen/LiveIntervals.h"
3 #include "llvm/CodeGen/MIRParser/MIRParser.h"
4 #include "llvm/CodeGen/MachineFunction.h"
5 #include "llvm/CodeGen/MachineModuleInfo.h"
6 #include "llvm/CodeGen/TargetRegisterInfo.h"
7 #include "llvm/IR/LegacyPassManager.h"
8 #include "llvm/Support/MemoryBuffer.h"
9 #include "llvm/Support/SourceMgr.h"
10 #include "llvm/Support/TargetRegistry.h"
11 #include "llvm/Support/TargetSelect.h"
12 #include "llvm/Target/TargetMachine.h"
13 #include "llvm/Target/TargetOptions.h"
14 #include "gtest/gtest.h"
19 void initializeTestPassPass(PassRegistry
&);
25 InitializeAllTargets();
26 InitializeAllTargetMCs();
27 InitializeAllAsmPrinters();
28 InitializeAllAsmParsers();
30 PassRegistry
*Registry
= PassRegistry::getPassRegistry();
31 initializeCore(*Registry
);
32 initializeCodeGen(*Registry
);
35 /// Create a TargetMachine. As we lack a dedicated always available target for
36 /// unittests, we go for "AMDGPU" to be able to test normal and subregister
38 std::unique_ptr
<LLVMTargetMachine
> createTargetMachine() {
39 Triple
TargetTriple("amdgcn--");
41 const Target
*T
= TargetRegistry::lookupTarget("", TargetTriple
, Error
);
45 TargetOptions Options
;
46 return std::unique_ptr
<LLVMTargetMachine
>(static_cast<LLVMTargetMachine
*>(
47 T
->createTargetMachine("AMDGPU", "", "", Options
, None
, None
,
48 CodeGenOpt::Aggressive
)));
51 std::unique_ptr
<Module
> parseMIR(LLVMContext
&Context
,
52 legacy::PassManagerBase
&PM
, std::unique_ptr
<MIRParser
> &MIR
,
53 const LLVMTargetMachine
&TM
, StringRef MIRCode
, const char *FuncName
) {
54 SMDiagnostic Diagnostic
;
55 std::unique_ptr
<MemoryBuffer
> MBuffer
= MemoryBuffer::getMemBuffer(MIRCode
);
56 MIR
= createMIRParser(std::move(MBuffer
), Context
);
60 std::unique_ptr
<Module
> M
= MIR
->parseIRModule();
64 M
->setDataLayout(TM
.createDataLayout());
66 MachineModuleInfoWrapperPass
*MMIWP
= new MachineModuleInfoWrapperPass(&TM
);
67 if (MIR
->parseMachineFunctions(*M
, MMIWP
->getMMI()))
74 typedef std::function
<void(MachineFunction
&,LiveIntervals
&)> LiveIntervalTest
;
76 struct TestPass
: public MachineFunctionPass
{
78 TestPass() : MachineFunctionPass(ID
) {
79 // We should never call this but always use PM.add(new TestPass(...))
82 TestPass(LiveIntervalTest T
) : MachineFunctionPass(ID
), T(T
) {
83 initializeTestPassPass(*PassRegistry::getPassRegistry());
86 bool runOnMachineFunction(MachineFunction
&MF
) override
{
87 LiveIntervals
&LIS
= getAnalysis
<LiveIntervals
>();
89 EXPECT_TRUE(MF
.verify(this));
93 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
95 AU
.addRequired
<LiveIntervals
>();
96 AU
.addPreserved
<LiveIntervals
>();
97 MachineFunctionPass::getAnalysisUsage(AU
);
103 static MachineInstr
&getMI(MachineFunction
&MF
, unsigned At
,
105 MachineBasicBlock
&MBB
= *MF
.getBlockNumbered(BlockNum
);
108 for (MachineInstr
&MI
: MBB
) {
113 llvm_unreachable("Instruction not found");
117 * Move instruction number \p From in front of instruction number \p To and
118 * update affected liveness intervals with LiveIntervalAnalysis::handleMove().
120 static void testHandleMove(MachineFunction
&MF
, LiveIntervals
&LIS
,
121 unsigned From
, unsigned To
, unsigned BlockNum
= 0) {
122 MachineInstr
&FromInstr
= getMI(MF
, From
, BlockNum
);
123 MachineInstr
&ToInstr
= getMI(MF
, To
, BlockNum
);
125 MachineBasicBlock
&MBB
= *FromInstr
.getParent();
126 MBB
.splice(ToInstr
.getIterator(), &MBB
, FromInstr
.getIterator());
127 LIS
.handleMove(FromInstr
, true);
130 static void liveIntervalTest(StringRef MIRFunc
, LiveIntervalTest T
) {
132 std::unique_ptr
<LLVMTargetMachine
> TM
= createTargetMachine();
133 // This test is designed for the X86 backend; stop if it is not available.
137 legacy::PassManager PM
;
140 StringRef MIRString
= (Twine(R
"MIR(
145 - { id: 0, class: sreg_64 }
148 )MIR") + Twine(MIRFunc
) + Twine("...\n")).toNullTerminatedStringRef(S
);
149 std::unique_ptr
<MIRParser
> MIR
;
150 std::unique_ptr
<Module
> M
= parseMIR(Context
, PM
, MIR
, *TM
, MIRString
,
154 PM
.add(new TestPass(T
));
159 } // End of anonymous namespace.
161 char TestPass::ID
= 0;
162 INITIALIZE_PASS(TestPass
, "testpass", "testpass", false, false)
164 TEST(LiveIntervalTest
, MoveUpDef
) {
166 liveIntervalTest(R
"MIR(
169 early-clobber %0 = IMPLICIT_DEF
171 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
172 testHandleMove(MF
, LIS
, 2, 1);
176 TEST(LiveIntervalTest
, MoveUpRedef
) {
177 liveIntervalTest(R
"MIR(
180 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
182 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
183 testHandleMove(MF
, LIS
, 2, 1);
187 TEST(LiveIntervalTest
, MoveUpEarlyDef
) {
188 liveIntervalTest(R
"MIR(
191 early-clobber %0 = IMPLICIT_DEF
193 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
194 testHandleMove(MF
, LIS
, 2, 1);
198 TEST(LiveIntervalTest
, MoveUpEarlyRedef
) {
199 liveIntervalTest(R
"MIR(
202 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
204 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
205 testHandleMove(MF
, LIS
, 2, 1);
209 TEST(LiveIntervalTest
, MoveUpKill
) {
210 liveIntervalTest(R
"MIR(
214 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
215 testHandleMove(MF
, LIS
, 2, 1);
219 TEST(LiveIntervalTest
, MoveUpKillFollowing
) {
220 liveIntervalTest(R
"MIR(
225 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
226 testHandleMove(MF
, LIS
, 2, 1);
230 // TODO: Construct a situation where we have intervals following a hole
231 // while still having connected components.
233 TEST(LiveIntervalTest
, MoveDownDef
) {
235 liveIntervalTest(R
"MIR(
237 early-clobber %0 = IMPLICIT_DEF
240 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
241 testHandleMove(MF
, LIS
, 1, 2);
245 TEST(LiveIntervalTest
, MoveDownRedef
) {
246 liveIntervalTest(R
"MIR(
248 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
251 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
252 testHandleMove(MF
, LIS
, 1, 2);
256 TEST(LiveIntervalTest
, MoveDownEarlyDef
) {
257 liveIntervalTest(R
"MIR(
259 early-clobber %0 = IMPLICIT_DEF
262 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
263 testHandleMove(MF
, LIS
, 1, 2);
267 TEST(LiveIntervalTest
, MoveDownEarlyRedef
) {
268 liveIntervalTest(R
"MIR(
270 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
273 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
274 testHandleMove(MF
, LIS
, 1, 2);
278 TEST(LiveIntervalTest
, MoveDownKill
) {
279 liveIntervalTest(R
"MIR(
283 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
284 testHandleMove(MF
, LIS
, 1, 2);
288 TEST(LiveIntervalTest
, MoveDownKillFollowing
) {
289 liveIntervalTest(R
"MIR(
294 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
295 testHandleMove(MF
, LIS
, 1, 2);
299 TEST(LiveIntervalTest
, MoveUndefUse
) {
300 liveIntervalTest(R
"MIR(
302 S_NOP 0, implicit undef %0
305 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
306 testHandleMove(MF
, LIS
, 1, 3);
310 TEST(LiveIntervalTest
, MoveUpValNos
) {
311 // handleMoveUp() had a bug where it would reuse the value number of the
312 // destination segment, even though we have no guarantee that this valno
313 // wasn't used in other segments.
314 liveIntervalTest(R
"MIR(
315 successors: %bb.1, %bb.2
317 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
323 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
324 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
325 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
327 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
328 testHandleMove(MF
, LIS
, 2, 0, 2);
332 TEST(LiveIntervalTest
, MoveOverUndefUse0
) {
333 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
334 liveIntervalTest(R
"MIR(
337 S_NOP 0, implicit undef %0
338 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
339 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
340 testHandleMove(MF
, LIS
, 3, 1);
344 TEST(LiveIntervalTest
, MoveOverUndefUse1
) {
345 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
346 liveIntervalTest(R
"MIR(
347 $sgpr0 = IMPLICIT_DEF
349 S_NOP 0, implicit undef $sgpr0
350 $sgpr0 = IMPLICIT_DEF implicit $sgpr0(tied-def 0)
351 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
352 testHandleMove(MF
, LIS
, 3, 1);
356 TEST(LiveIntervalTest
, SubRegMoveDown
) {
357 // Subregister ranges can have holes inside a basic block. Check for a
358 // movement of the form 32->150 in a liverange [16, 32) [100,200).
359 liveIntervalTest(R
"MIR(
360 successors: %bb.1, %bb.2
362 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
366 S_NOP 0, implicit %0.sub0
367 S_NOP 0, implicit %0.sub1
369 undef %0.sub0 = IMPLICIT_DEF
370 %0.sub1 = IMPLICIT_DEF
373 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
374 // Scheduler behaviour: Clear def,read-undef flag and move.
375 MachineInstr
&MI
= getMI(MF
, 3, /*BlockNum=*/1);
376 MI
.getOperand(0).setIsUndef(false);
377 testHandleMove(MF
, LIS
, 1, 4, /*BlockNum=*/1);
381 TEST(LiveIntervalTest
, SubRegMoveUp
) {
382 // handleMoveUp had a bug not updating valno of segment incoming to bb.2
383 // after swapping subreg definitions.
384 liveIntervalTest(R
"MIR(
385 successors: %bb.1, %bb.2
386 undef %0.sub0 = IMPLICIT_DEF
387 %0.sub1 = IMPLICIT_DEF
388 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
391 S_NOP 0, implicit %0.sub1
393 S_NOP 0, implicit %0.sub1
394 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
395 testHandleMove(MF
, LIS
, 1, 0);
399 TEST(LiveIntervalTest
, DeadSubRegMoveUp
) {
400 // handleMoveUp had a bug where moving a dead subreg def into the middle of
401 // an earlier segment resulted in an invalid live range.
402 liveIntervalTest(R
"MIR(
403 undef %125.sub0:vreg_128 = V_MOV_B32_e32 0, implicit $exec
404 %125.sub1:vreg_128 = COPY %125.sub0
405 %125.sub2:vreg_128 = COPY %125.sub0
406 undef %51.sub0:vreg_128 = V_MOV_B32_e32 898625526, implicit $exec
407 %51.sub1:vreg_128 = COPY %51.sub0
408 %51.sub2:vreg_128 = COPY %51.sub0
409 %52:vgpr_32 = V_MOV_B32_e32 986714345, implicit $exec
410 %54:vgpr_32 = V_MOV_B32_e32 1742342378, implicit $exec
411 %57:vgpr_32 = V_MOV_B32_e32 3168768712, implicit $exec
412 %59:vgpr_32 = V_MOV_B32_e32 1039972644, implicit $exec
413 %60:vgpr_32 = V_MAD_F32 0, %52, 0, undef %61:vgpr_32, 0, %59, 0, 0, implicit $exec
414 %63:vgpr_32 = V_ADD_F32_e32 %51.sub3, undef %64:vgpr_32, implicit $exec
415 dead %66:vgpr_32 = V_MAD_F32 0, %60, 0, undef %67:vgpr_32, 0, %125.sub2, 0, 0, implicit $exec
416 undef %124.sub1:vreg_128 = V_MAD_F32 0, %57, 0, undef %70:vgpr_32, 0, %125.sub1, 0, 0, implicit $exec
417 %124.sub0:vreg_128 = V_MAD_F32 0, %54, 0, undef %73:vgpr_32, 0, %125.sub0, 0, 0, implicit $exec
418 dead undef %125.sub3:vreg_128 = V_MAC_F32_e32 %63, undef %76:vgpr_32, %125.sub3, implicit $exec
419 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
420 testHandleMove(MF
, LIS
, 15, 12);
424 TEST(LiveIntervalTest
, TestMoveSubRegDefAcrossUseDef
) {
425 liveIntervalTest(R
"MIR(
426 %1:vreg_64 = IMPLICIT_DEF
429 %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec
430 %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec
431 undef %1.sub0:vreg_64 = V_ADD_U32_e32 %2, %2, implicit $exec
432 %1.sub1:vreg_64 = COPY %2
433 S_NOP 0, implicit %1.sub1
436 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
437 MachineInstr
&UndefSubregDef
= getMI(MF
, 2, 1);
438 // The scheduler clears undef from subregister defs before moving
439 UndefSubregDef
.getOperand(0).setIsUndef(false);
440 testHandleMove(MF
, LIS
, 3, 1, 1);
444 TEST(LiveIntervalTest
, TestMoveSubRegDefAcrossUseDefMulti
) {
445 liveIntervalTest(R
"MIR(
446 %1:vreg_96 = IMPLICIT_DEF
449 %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec
450 %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec
451 undef %1.sub0:vreg_96 = V_ADD_U32_e32 %2, %2, implicit $exec
452 %1.sub1:vreg_96 = COPY %2
453 %1.sub2:vreg_96 = COPY %2
454 S_NOP 0, implicit %1.sub1, implicit %1.sub2
457 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
458 MachineInstr
&UndefSubregDef
= getMI(MF
, 2, 1);
459 // The scheduler clears undef from subregister defs before moving
460 UndefSubregDef
.getOperand(0).setIsUndef(false);
461 testHandleMove(MF
, LIS
, 4, 1, 1);
464 int main(int argc
, char **argv
) {
465 ::testing::InitGoogleTest(&argc
, argv
);
467 return RUN_ALL_TESTS();