From bda54bca391de6b83a2131bf6344d3a2ae8eca34 Mon Sep 17 00:00:00 2001 From: Luke Cheeseman Date: Mon, 24 Sep 2018 10:42:22 +0000 Subject: [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 --- llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'llvm/lib/Target/ARM') diff --git a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp index bb79783e15b..e6b8f2fcf45 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::max() -- cgit v1.2.3