diff options
| author | Stefan Maksimovic <stefan.maksimovic@mips.com> | 2018-02-09 13:55:25 +0000 |
|---|---|---|
| committer | Stefan Maksimovic <stefan.maksimovic@mips.com> | 2018-02-09 13:55:25 +0000 |
| commit | dc66ae78c68f7a3094d4667bc103a216d2bd52ac (patch) | |
| tree | 7edfbb59c4f4e5d0509cdc0ed25a915c8c311610 /llvm/lib/CodeGen | |
| parent | b6ad25cd4ce8df28a8c0f86386f6e60e44ea5d1c (diff) | |
| download | bcm5719-llvm-dc66ae78c68f7a3094d4667bc103a216d2bd52ac.tar.gz bcm5719-llvm-dc66ae78c68f7a3094d4667bc103a216d2bd52ac.zip | |
[SelectionDAG] Provide adequate register class for RegisterSDNode
When adding operands to machine instructions in case of
RegisterSDNodes, generate a COPY node in case the register class
does not match the one in the instruction definition.
Differental Revision: https://reviews.llvm.org/D35561
llvm-svn: 324733
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp index cc9b41b4b48..0a991f49245 100644 --- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -394,11 +394,26 @@ void InstrEmitter::AddOperand(MachineInstrBuilder &MIB, } else if (ConstantFPSDNode *F = dyn_cast<ConstantFPSDNode>(Op)) { MIB.addFPImm(F->getConstantFPValue()); } else if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(Op)) { + unsigned VReg = R->getReg(); + MVT OpVT = Op.getSimpleValueType(); + const TargetRegisterClass *OpRC = + TLI->isTypeLegal(OpVT) ? TLI->getRegClassFor(OpVT) : nullptr; + const TargetRegisterClass *IIRC = + II ? TRI->getAllocatableClass(TII->getRegClass(*II, IIOpNum, TRI, *MF)) + : nullptr; + + if (OpRC && IIRC && OpRC != IIRC && + TargetRegisterInfo::isVirtualRegister(VReg)) { + unsigned NewVReg = MRI->createVirtualRegister(IIRC); + BuildMI(*MBB, InsertPos, Op.getNode()->getDebugLoc(), + TII->get(TargetOpcode::COPY), NewVReg).addReg(VReg); + VReg = NewVReg; + } // Turn additional physreg operands into implicit uses on non-variadic // instructions. This is used by call and return instructions passing // arguments in registers. bool Imp = II && (IIOpNum >= II->getNumOperands() && !II->isVariadic()); - MIB.addReg(R->getReg(), getImplRegState(Imp)); + MIB.addReg(VReg, getImplRegState(Imp)); } else if (RegisterMaskSDNode *RM = dyn_cast<RegisterMaskSDNode>(Op)) { MIB.addRegMask(RM->getRegMask()); } else if (GlobalAddressSDNode *TGA = dyn_cast<GlobalAddressSDNode>(Op)) { |

