diff options
author | Evgeny Astigeevich <evgeny.astigeevich@arm.com> | 2017-08-24 10:00:25 +0000 |
---|---|---|
committer | Evgeny Astigeevich <evgeny.astigeevich@arm.com> | 2017-08-24 10:00:25 +0000 |
commit | 540a39adf7f0c1190249e6a3c9b5a13bd20d80d9 (patch) | |
tree | a38e1dbde2638477d4aadf7596fb5b1acc96cda1 /llvm/lib | |
parent | 78027437e6150666e7d04ffbef1d28131182044c (diff) | |
download | bcm5719-llvm-540a39adf7f0c1190249e6a3c9b5a13bd20d80d9.tar.gz bcm5719-llvm-540a39adf7f0c1190249e6a3c9b5a13bd20d80d9.zip |
[ARM, Thumb1] Prevent ARMTargetLowering::isLegalAddressingMode from accepting illegal modes
ARMTargetLowering::isLegalAddressingMode can accept illegal addressing modes
for the Thumb1 target. This causes generation of redundant code and affects
performance.
This fixes PR34106: https://bugs.llvm.org/show_bug.cgi?id=34106
Differential Revision: https://reviews.llvm.org/D36467
llvm-svn: 311649
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.cpp | 22 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.h | 4 |
2 files changed, 22 insertions, 4 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 03d0b7e2a74..8d04f59b95c 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -12383,6 +12383,21 @@ bool ARMTargetLowering::isLegalT2ScaledAddressingMode(const AddrMode &AM, } } +bool ARMTargetLowering::isLegalT1ScaledAddressingMode(const AddrMode &AM, + EVT VT) const { + const int Scale = AM.Scale; + + // Negative scales are not supported in Thumb1. + if (Scale < 0) + return false; + + // Thumb1 addressing modes do not support register scaling excepting the + // following cases: + // 1. Scale == 1 means no scaling. + // 2. Scale == 2 this can be lowered to r + r if there is no base register. + return (Scale == 1) || (!AM.HasBaseReg && Scale == 2); +} + /// isLegalAddressingMode - Return true if the addressing mode represented /// by AM is legal for this target, for a load/store of the specified type. bool ARMTargetLowering::isLegalAddressingMode(const DataLayout &DL, @@ -12399,10 +12414,6 @@ bool ARMTargetLowering::isLegalAddressingMode(const DataLayout &DL, switch (AM.Scale) { case 0: // no scale reg, must be "r+i" or "r", or "i". break; - case 1: - if (Subtarget->isThumb1Only()) - return false; - LLVM_FALLTHROUGH; default: // ARM doesn't support any R+R*scale+imm addr modes. if (AM.BaseOffs) @@ -12411,6 +12422,9 @@ bool ARMTargetLowering::isLegalAddressingMode(const DataLayout &DL, if (!VT.isSimple()) return false; + if (Subtarget->isThumb1Only()) + return isLegalT1ScaledAddressingMode(AM, VT); + if (Subtarget->isThumb2()) return isLegalT2ScaledAddressingMode(AM, VT); diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h index 7761aa1315e..fd93629f084 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.h +++ b/llvm/lib/Target/ARM/ARMISelLowering.h @@ -329,6 +329,10 @@ class InstrItineraryData; bool isLegalT2ScaledAddressingMode(const AddrMode &AM, EVT VT) const; + /// \brief Returns true if the addresing mode representing by AM is legal + /// for the Thumb1 target, for a load/store of the specified type. + bool isLegalT1ScaledAddressingMode(const AddrMode &AM, EVT VT) const; + /// isLegalICmpImmediate - Return true if the specified immediate is legal /// icmp immediate, that is the target has icmp instructions which can /// compare a register against the immediate without having to materialize |