summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorEvgeny Astigeevich <evgeny.astigeevich@arm.com>2017-08-24 10:00:25 +0000
committerEvgeny Astigeevich <evgeny.astigeevich@arm.com>2017-08-24 10:00:25 +0000
commit540a39adf7f0c1190249e6a3c9b5a13bd20d80d9 (patch)
treea38e1dbde2638477d4aadf7596fb5b1acc96cda1 /llvm/lib
parent78027437e6150666e7d04ffbef1d28131182044c (diff)
downloadbcm5719-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.cpp22
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.h4
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
OpenPOWER on IntegriCloud