Don't fold insufficiently aligned ldr/str into ldm/stm instructions.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 14 Jan 2010 00:54:10 +0000 (00:54 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 14 Jan 2010 00:54:10 +0000 (00:54 +0000)
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

lib/Target/ARM/ARMLoadStoreOptimizer.cpp

index b13f98acb78123b7d545a9b6e5d341bca13f75d3..b78b95b22ebfc4086dee705e5503185dd5e53ccf 100644 (file)
@@ -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;