aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
diff options
context:
space:
mode:
authorLuke Cheeseman <luke.cheeseman@arm.com>2018-09-24 10:42:22 +0000
committerLuke Cheeseman <luke.cheeseman@arm.com>2018-09-24 10:42:22 +0000
commitbda54bca391de6b83a2131bf6344d3a2ae8eca34 (patch)
tree9428d980c44f9214a6fa526bf2910b72f1180a5b /llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
parentc451c9ef50b7b3df260e709a9dcd6324356d57a2 (diff)
downloadllvm-bda54bca391de6b83a2131bf6344d3a2ae8eca34.zip
llvm-bda54bca391de6b83a2131bf6344d3a2ae8eca34.tar.gz
llvm-bda54bca391de6b83a2131bf6344d3a2ae8eca34.tar.bz2
[ARM][ARMLoadStoreOptimizer]
- The load store optimizer is currently merging multiple loads/stores into VLDM/VSTM with more than 16 doubleword registers - This is an UNPREDICTABLE instruction and shouldn't be done - It looks like the Limit for how many registers included in a merge got dropped at some point so I am reintroducing it in this patch - This fixes https://bugs.llvm.org/show_bug.cgi?id=38389 Differential Revision: https://reviews.llvm.org/D52085 llvm-svn: 342872
Diffstat (limited to 'llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp14
1 files changed, 14 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
index bb79783..e6b8f2f 100644
--- a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -1027,6 +1027,18 @@ void ARMLoadStoreOpt::FormCandidates(const MemOpQueue &MemOps) {
if (AssumeMisalignedLoadStores && !mayCombineMisaligned(*STI, *MI))
CanMergeToLSMulti = CanMergeToLSDouble = false;
+ // vldm / vstm limit are 32 for S variants, 16 for D variants.
+ unsigned Limit;
+ switch (Opcode) {
+ default:
+ Limit = UINT_MAX;
+ break;
+ case ARM::VLDRD:
+ case ARM::VSTRD:
+ Limit = 16;
+ break;
+ }
+
// Merge following instructions where possible.
for (unsigned I = SIndex+1; I < EIndex; ++I, ++Count) {
int NewOffset = MemOps[I].Offset;
@@ -1036,6 +1048,8 @@ void ARMLoadStoreOpt::FormCandidates(const MemOpQueue &MemOps) {
unsigned Reg = MO.getReg();
if (Reg == ARM::SP || Reg == ARM::PC)
break;
+ if (Count == Limit)
+ break;
// See if the current load/store may be part of a multi load/store.
unsigned RegNum = MO.isUndef() ? std::numeric_limits<unsigned>::max()