summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorArtyom Skrobov <Artyom.Skrobov@arm.com>2014-02-26 11:27:28 +0000
committerArtyom Skrobov <Artyom.Skrobov@arm.com>2014-02-26 11:27:28 +0000
commite7082383732df492d8fabd17c31300db08de7627 (patch)
tree449d776a03de2b2c617ed0252b2abf17e5681cc3 /lib
parent3d0b46969073ca31a74b5a19c16163b6b24fb770 (diff)
downloadllvm-e7082383732df492d8fabd17c31300db08de7627.tar.gz
llvm-e7082383732df492d8fabd17c31300db08de7627.tar.bz2
llvm-e7082383732df492d8fabd17c31300db08de7627.tar.xz
ARMv8 IfConversion must skip narrow instructions that a) define CPSR and b) wouldn't affect CPSR in an IT block
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202257 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.cpp14
-rw-r--r--lib/Target/ARM/ARMFeatures.h37
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp4
3 files changed, 39 insertions, 16 deletions
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp
index a244c5fb8a..320f54a327 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -535,6 +535,20 @@ bool ARMBaseInstrInfo::isPredicable(MachineInstr *MI) const {
return true;
}
+template<> bool IsCPSRDead<MachineInstr>(MachineInstr* MI) {
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = MI->getOperand(i);
+ if (!MO.isReg() || MO.isUndef() || MO.isUse())
+ continue;
+ if (MO.getReg() != ARM::CPSR)
+ continue;
+ if (!MO.isDead())
+ return false;
+ }
+ // all definitions of CPSR are dead
+ return true;
+}
+
/// FIXME: Works around a gcc miscompilation with -fstrict-aliasing.
LLVM_ATTRIBUTE_NOINLINE
static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
diff --git a/lib/Target/ARM/ARMFeatures.h b/lib/Target/ARM/ARMFeatures.h
index 2580f7bf7f..e2a228c18a 100644
--- a/lib/Target/ARM/ARMFeatures.h
+++ b/lib/Target/ARM/ARMFeatures.h
@@ -16,6 +16,9 @@
#include "ARM.h"
+template<typename InstrType> // could be MachineInstr or MCInst
+bool IsCPSRDead(InstrType *Instr);
+
namespace llvm {
template<typename InstrType> // could be MachineInstr or MCInst
@@ -26,25 +29,12 @@ inline bool isV8EligibleForIT(InstrType *Instr) {
case ARM::tADC:
case ARM::tADDi3:
case ARM::tADDi8:
- case ARM::tADDrSPi:
case ARM::tADDrr:
case ARM::tAND:
case ARM::tASRri:
case ARM::tASRrr:
case ARM::tBIC:
- case ARM::tCMNz:
- case ARM::tCMPi8:
- case ARM::tCMPr:
case ARM::tEOR:
- case ARM::tLDRBi:
- case ARM::tLDRBr:
- case ARM::tLDRHi:
- case ARM::tLDRHr:
- case ARM::tLDRSB:
- case ARM::tLDRSH:
- case ARM::tLDRi:
- case ARM::tLDRr:
- case ARM::tLDRspi:
case ARM::tLSLri:
case ARM::tLSLrr:
case ARM::tLSRri:
@@ -56,6 +46,24 @@ inline bool isV8EligibleForIT(InstrType *Instr) {
case ARM::tROR:
case ARM::tRSB:
case ARM::tSBC:
+ case ARM::tSUBi3:
+ case ARM::tSUBi8:
+ case ARM::tSUBrr:
+ // Outside of an IT block, these set CPSR.
+ return IsCPSRDead(Instr);
+ case ARM::tADDrSPi:
+ case ARM::tCMNz:
+ case ARM::tCMPi8:
+ case ARM::tCMPr:
+ case ARM::tLDRBi:
+ case ARM::tLDRBr:
+ case ARM::tLDRHi:
+ case ARM::tLDRHr:
+ case ARM::tLDRSB:
+ case ARM::tLDRSH:
+ case ARM::tLDRi:
+ case ARM::tLDRr:
+ case ARM::tLDRspi:
case ARM::tSTRBi:
case ARM::tSTRBr:
case ARM::tSTRHi:
@@ -63,9 +71,6 @@ inline bool isV8EligibleForIT(InstrType *Instr) {
case ARM::tSTRi:
case ARM::tSTRr:
case ARM::tSTRspi:
- case ARM::tSUBi3:
- case ARM::tSUBi8:
- case ARM::tSUBrr:
case ARM::tTST:
return true;
// there are some "conditionally deprecated" opcodes
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 9bb1cf2b4c..7dc4d18a07 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -7850,6 +7850,10 @@ unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
return Match_Success;
}
+template<> inline bool IsCPSRDead<MCInst>(MCInst* Instr) {
+ return true; // In an assembly source, no need to second-guess
+}
+
static const char *getSubtargetFeatureName(unsigned Val);
bool ARMAsmParser::
MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,