diff options
Diffstat (limited to 'llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp index d78a26fee0f..bee5bfd7b2e 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -518,6 +518,13 @@ bool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI, return Found; } +static bool isCPSRDefined(const MachineInstr *MI) { + for (const auto &MO : MI->operands()) + if (MO.isReg() && MO.getReg() == ARM::CPSR && (MO.isDef() || !MO.isDead())) + return true; + return false; +} + /// isPredicable - Return true if the specified instruction can be predicated. /// By default, this returns true for every instruction with a /// PredicateOperand. @@ -525,6 +532,13 @@ bool ARMBaseInstrInfo::isPredicable(MachineInstr *MI) const { if (!MI->isPredicable()) return false; + // The ARM Architecture Reference Manual states that the CPSR may only be + // accessed by MUL in Thumb mode if it is outside an IT block. Thus, if CPSR + // is defined (or clobbered) by this instruction, it is not predicable. + if (MI->getOpcode() == ARM::tMUL || MI->getOpcode() == ARM::t2MUL) + if (isCPSRDefined(MI)) + return false; + ARMFunctionInfo *AFI = MI->getParent()->getParent()->getInfo<ARMFunctionInfo>(); |