aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2012-04-05 23:51:24 +0000
committerJim Grosbach <grosbach@apple.com>2012-04-05 23:51:24 +0000
commitd6a1a1dc2ff47c764eb1ae15b09027edf4ad7286 (patch)
tree86766faef828c0ca64fed67493c19296bd4c5566 /llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
parenta974688d353881cb37f6b834bb40377545505c26 (diff)
downloadllvm-d6a1a1dc2ff47c764eb1ae15b09027edf4ad7286.zip
llvm-d6a1a1dc2ff47c764eb1ae15b09027edf4ad7286.tar.gz
llvm-d6a1a1dc2ff47c764eb1ae15b09027edf4ad7286.tar.bz2
ARM: Don't form a t2LDRi8 or t2STRi8 with an offset of zero.
The load/store optimizer splits LDRD/STRD into two instructions when the register pairing doesn't work out. For negative offsets in Thumb2, it uses t2STRi8 to do that. That's fine, except for the case when the offset is in the range [-4,-1]. In that case, we'll also form a second t2STRi8 with the original offset plus 4, resulting in a t2STRi8 with a non-negative offset, which ends up as if it were an STRT, which is completely bogus. Similarly for loads. No testcase, unfortunately, as any I've been able to construct is both large and extremely fragile. rdar://11193937 llvm-svn: 154141
Diffstat (limited to 'llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp8
1 files changed, 8 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
index 5770f77..b632c78 100644
--- a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -1172,6 +1172,10 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB,
BaseReg, false, BaseUndef, false, OffUndef,
Pred, PredReg, TII, isT2);
NewBBI = llvm::prior(MBBI);
+ // Be extra careful for thumb2. t2LDRi8 can't reference a zero offset,
+ // so adjust and use t2LDRi12 here for that.
+ if (isT2 && NewOpc == ARM::t2LDRi8 && OffImm+4 >= 0)
+ NewOpc = ARM::t2LDRi12;
InsertLDR_STR(MBB, MBBI, OffImm, isLd, dl, NewOpc,
EvenReg, EvenDeadKill, false,
BaseReg, BaseKill, BaseUndef, OffKill, OffUndef,
@@ -1193,6 +1197,10 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB,
BaseReg, false, BaseUndef, false, OffUndef,
Pred, PredReg, TII, isT2);
NewBBI = llvm::prior(MBBI);
+ // Be extra careful for thumb2. t2STRi8 can't reference a zero offset,
+ // so adjust and use t2STRi12 here for that.
+ if (isT2 && NewOpc == ARM::t2STRi8 && OffImm+4 >= 0)
+ NewOpc = ARM::t2STRi12;
InsertLDR_STR(MBB, MBBI, OffImm+4, isLd, dl, NewOpc,
OddReg, OddDeadKill, OddUndef,
BaseReg, BaseKill, BaseUndef, OffKill, OffUndef,