Index: include/llvm/Target/TargetRegisterInfo.h =================================================================== --- include/llvm/Target/TargetRegisterInfo.h +++ include/llvm/Target/TargetRegisterInfo.h @@ -846,6 +846,12 @@ const TargetRegisterClass *NewRC) const { return true; } + /// \brief No risk to coalescing into reserved physical register if this + /// returns true. + virtual bool shouldCoalesceReservedPhysReg(unsigned DstReg, + MachineInstr *DestMI) const + { return true; } + //===--------------------------------------------------------------------===// /// Debug information queries. Index: lib/CodeGen/RegisterCoalescer.cpp =================================================================== --- lib/CodeGen/RegisterCoalescer.cpp +++ lib/CodeGen/RegisterCoalescer.cpp @@ -1532,6 +1532,12 @@ } } + if (!TRI->shouldCoalesceReservedPhysReg(DstReg, DestMI)) { + DEBUG(dbgs() << "\tSubtarget bailed on coalescing" + << "into reserved physical register.\n"); + return false; + } + // We're going to remove the copy which defines a physical reserved // register, so remove its valno, etc. DEBUG(dbgs() << "\t\tRemoving phys reg def of " << DstReg << " at " Index: lib/Target/ARM/ARMBaseRegisterInfo.h =================================================================== --- lib/Target/ARM/ARMBaseRegisterInfo.h +++ lib/Target/ARM/ARMBaseRegisterInfo.h @@ -177,13 +177,18 @@ int SPAdj, unsigned FIOperandNum, RegScavenger *RS = nullptr) const override; - /// \brief SrcRC and DstRC will be morphed into NewRC if this returns true + /// \brief SrcRC and DstRC will be morphed into NewRC if this returns true. bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg, const TargetRegisterClass *DstRC, unsigned DstSubReg, const TargetRegisterClass *NewRC) const override; + + /// \brief No risk to coalescing into reserved physical register if this + /// returns true. + bool shouldCoalesceReservedPhysReg(unsigned DestReg, + MachineInstr *DestMI) const override; }; } // end namespace llvm Index: lib/Target/ARM/ARMBaseRegisterInfo.cpp =================================================================== --- lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -819,3 +819,27 @@ } return false; } + +bool +ARMBaseRegisterInfo::shouldCoalesceReservedPhysReg(unsigned DstReg, + MachineInstr *DestMI) const { + // For t2SUBri, t2ADDri, t2SUBri12, and t2ADDri12, Rd is allowed to be SP + // if and only if Rn is SP + if (DstReg == ARM::SP) { + // We're trying to coalesce into SP, if DestMI looks like stack adjustment, + // i.e. t2SUBri or t2ADDri, and its Rn is not SP already, be conservative. + unsigned Opc = DestMI->getOpcode(); + switch (Opc) { + case ARM::t2SUBri: + case ARM::t2ADDri: + case ARM::t2SUBri12: + case ARM::t2ADDri12: { + unsigned SrcReg = DestMI->getOperand(1).getReg(); + if (!isPhysicalRegister(SrcReg) || (SrcReg != ARM::SP)) + return false; + } + default: return true; + } + } + return true; +}