diff options
author | David Green <david.green@arm.com> | 2022-06-19 18:55:19 +0100 |
---|---|---|
committer | David Green <david.green@arm.com> | 2022-06-19 18:55:19 +0100 |
commit | e995e34469be69d867dcf67935faead59feee9b1 (patch) | |
tree | 29c376b7d248d4a647a350cbc837979ba7b5782f /llvm/lib/CodeGen/ModuloSchedule.cpp | |
parent | 30c675878c21be9973faabddc38ebf1b4c603b7d (diff) | |
download | llvm-e995e34469be69d867dcf67935faead59feee9b1.zip llvm-e995e34469be69d867dcf67935faead59feee9b1.tar.gz llvm-e995e34469be69d867dcf67935faead59feee9b1.tar.bz2 |
[MachinePipeliner] Handle failing constrainRegClass
The included test hits a verifier problems as one of the instructions:
```
%113:tgpreven, %114:tgprodd = MVE_VMLSLDAVas16 %12:tgpreven(tied-def 0), %11:tgprodd(tied-def 1), %7:mqpr, %8:mqpr, 0, $noreg, $noreg
```
Has two inputs that come from different PHIs with the same base reg, but
conflicting regclasses:
```
%11:tgprodd = PHI %103:gpr, %bb.1, %16:gpr, %bb.2
%12:tgpreven = PHI %103:gpr, %bb.1, %17:gpr, %bb.2
```
The MachinePipeliner would attempt to use %103 for both the %11 and %12
operands in the prolog, constraining the register class to the common
subset of both. Unfortunately there are no registers that are both odd
and even, so the second constrainRegClass fails. Fix this situation by
inserting a COPY for the second if the call to constrainRegClass fails.
The register allocation can then fold that extra copy away. The register
allocation of Q regs changed with this test, but the R regs were the
same and no new instructions are needed in the final assembly.
Differential Revision: https://reviews.llvm.org/D127971
Diffstat (limited to 'llvm/lib/CodeGen/ModuloSchedule.cpp')
-rw-r--r-- | llvm/lib/CodeGen/ModuloSchedule.cpp | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/ModuloSchedule.cpp b/llvm/lib/CodeGen/ModuloSchedule.cpp index c0a2d1f..342891a 100644 --- a/llvm/lib/CodeGen/ModuloSchedule.cpp +++ b/llvm/lib/CodeGen/ModuloSchedule.cpp @@ -1163,8 +1163,17 @@ void ModuloScheduleExpander::rewriteScheduledInstr( if (!InProlog && !Phi->isPHI() && StagePhi < StageSched) ReplaceReg = NewReg; if (ReplaceReg) { - MRI.constrainRegClass(ReplaceReg, MRI.getRegClass(OldReg)); - UseOp.setReg(ReplaceReg); + const TargetRegisterClass *NRC = + MRI.constrainRegClass(ReplaceReg, MRI.getRegClass(OldReg)); + if (NRC) + UseOp.setReg(ReplaceReg); + else { + Register SplitReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg)); + BuildMI(*BB, UseMI, UseMI->getDebugLoc(), TII->get(TargetOpcode::COPY), + SplitReg) + .addReg(ReplaceReg); + UseOp.setReg(SplitReg); + } } } } @@ -1209,8 +1218,12 @@ void EliminateDeadPhis(MachineBasicBlock *MBB, MachineRegisterInfo &MRI, MI.eraseFromParent(); Changed = true; } else if (!KeepSingleSrcPhi && MI.getNumExplicitOperands() == 3) { - MRI.constrainRegClass(MI.getOperand(1).getReg(), - MRI.getRegClass(MI.getOperand(0).getReg())); + const TargetRegisterClass *ConstrainRegClass = + MRI.constrainRegClass(MI.getOperand(1).getReg(), + MRI.getRegClass(MI.getOperand(0).getReg())); + assert(ConstrainRegClass && + "Expected a valid constrained register class!"); + (void)ConstrainRegClass; MRI.replaceRegWith(MI.getOperand(0).getReg(), MI.getOperand(1).getReg()); if (LIS) @@ -1458,7 +1471,10 @@ Register KernelRewriter::phi(Register LoopReg, Optional<Register> InitReg, MachineInstr *MI = MRI.getVRegDef(R); MI->getOperand(1).setReg(InitReg.getValue()); Phis.insert({{LoopReg, InitReg.getValue()}, R}); - MRI.constrainRegClass(R, MRI.getRegClass(InitReg.getValue())); + const TargetRegisterClass *ConstrainRegClass = + MRI.constrainRegClass(R, MRI.getRegClass(InitReg.getValue())); + assert(ConstrainRegClass && "Expected a valid constrained register class!"); + (void)ConstrainRegClass; UndefPhis.erase(I); return R; } @@ -1467,8 +1483,12 @@ Register KernelRewriter::phi(Register LoopReg, Optional<Register> InitReg, if (!RC) RC = MRI.getRegClass(LoopReg); Register R = MRI.createVirtualRegister(RC); - if (InitReg.hasValue()) - MRI.constrainRegClass(R, MRI.getRegClass(*InitReg)); + if (InitReg.hasValue()) { + const TargetRegisterClass *ConstrainRegClass = + MRI.constrainRegClass(R, MRI.getRegClass(*InitReg)); + assert(ConstrainRegClass && "Expected a valid constrained register class!"); + (void)ConstrainRegClass; + } BuildMI(*BB, BB->getFirstNonPHI(), DebugLoc(), TII->get(TargetOpcode::PHI), R) .addReg(InitReg.hasValue() ? *InitReg : undef(RC)) .addMBB(PreheaderBB) |