summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorStefan Maksimovic <stefan.maksimovic@mips.com>2018-02-09 13:55:25 +0000
committerStefan Maksimovic <stefan.maksimovic@mips.com>2018-02-09 13:55:25 +0000
commitdc66ae78c68f7a3094d4667bc103a216d2bd52ac (patch)
tree7edfbb59c4f4e5d0509cdc0ed25a915c8c311610 /llvm/lib/CodeGen
parentb6ad25cd4ce8df28a8c0f86386f6e60e44ea5d1c (diff)
downloadbcm5719-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.cpp17
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)) {
OpenPOWER on IntegriCloud