diff options
| author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2010-01-14 00:54:10 +0000 |
|---|---|---|
| committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2010-01-14 00:54:10 +0000 |
| commit | 99fc640242e391ba584711dc5f80780a90e8f5e4 (patch) | |
| tree | e18a2e5782f83df4d10f5570cb72ff18e7be6bec /lib/Target/ARM/ARMLoadStoreOptimizer.cpp | |
| parent | 5d43a33d221a6cb8870df5562fbf94f6ffcdc8b9 (diff) | |
| download | external_llvm-99fc640242e391ba584711dc5f80780a90e8f5e4.zip external_llvm-99fc640242e391ba584711dc5f80780a90e8f5e4.tar.gz external_llvm-99fc640242e391ba584711dc5f80780a90e8f5e4.tar.bz2 | |
Don't fold insufficiently aligned ldr/str into ldm/stm instructions.
An unaligned ldr causes a trap, and is then emulated by the kernel with
awesome performance. The darwin kernel does not emulate unaligned ldm/stm
Thumb2 instructions, so don't generate them.
This fixes the miscompilation of Multisource/Applications/JM/lencod for Thumb2.
Generating unaligned ldr/str pairs from a 16-bit aligned memcpy is probably
also a bad idea, but that is beyond the scope of this patch.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93393 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMLoadStoreOptimizer.cpp')
| -rw-r--r-- | lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp index b13f98a..b78b95b 100644 --- a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp +++ b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp @@ -740,6 +740,18 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineBasicBlock &MBB, /// isMemoryOp - Returns true if instruction is a memory operations (that this /// pass is capable of operating on). static bool isMemoryOp(const MachineInstr *MI) { + if (MI->hasOneMemOperand()) { + const MachineMemOperand *MMO = *MI->memoperands_begin(); + + // Don't touch volatile memory accesses - we may be changing their order. + if (MMO->isVolatile()) + return false; + + // Unaligned ldr/str is emulated by some kernels, but unaligned ldm/stm is not. + if (MMO->getAlignment() < 4) + return false; + } + int Opcode = MI->getOpcode(); switch (Opcode) { default: break; |
