[llvm-commits] [llvm] r128759 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp test/CodeGen/ARM/fp-arg-shuffle.ll

Cameron Zwarich zwarich at apple.com
Fri Apr 1 19:40:43 PDT 2011


Author: zwarich
Date: Fri Apr  1 21:40:43 2011
New Revision: 128759

URL: http://llvm.org/viewvc/llvm-project?rev=128759&view=rev
Log:
Do some peephole optimizations to remove pointless VMOVs from Neon to integer
registers that arise from argument shuffling with the soft float ABI. These
instructions are particularly slow on Cortex A8. This fixes one half of
<rdar://problem/8674845>.

Added:
    llvm/trunk/test/CodeGen/ARM/fp-arg-shuffle.ll
Modified:
    llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp

Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=128759&r1=128758&r2=128759&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Apr  1 21:40:43 2011
@@ -5561,6 +5561,37 @@
   SDValue InDouble = N->getOperand(0);
   if (InDouble.getOpcode() == ARMISD::VMOVDRR)
     return DCI.CombineTo(N, InDouble.getOperand(0), InDouble.getOperand(1));
+
+  // vmovrrd(load f64) -> (load i32), (load i32)
+  SDNode *InNode = InDouble.getNode();
+  if (ISD::isNormalLoad(InNode) && InNode->hasOneUse() &&
+      InNode->getValueType(0) == MVT::f64 &&
+      InNode->getOperand(1).getOpcode() == ISD::FrameIndex &&
+      !cast<LoadSDNode>(InNode)->isVolatile()) {
+    // TODO: Should this be done for non-FrameIndex operands?
+    LoadSDNode *LD = cast<LoadSDNode>(InNode);
+
+    SelectionDAG &DAG = DCI.DAG;
+    DebugLoc DL = LD->getDebugLoc();
+    SDValue BasePtr = LD->getBasePtr();
+    SDValue NewLD1 = DAG.getLoad(MVT::i32, DL, LD->getChain(), BasePtr,
+                                 LD->getPointerInfo(), LD->isVolatile(),
+                                 LD->isNonTemporal(), LD->getAlignment());
+
+    SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr,
+                                    DAG.getConstant(4, MVT::i32));
+    SDValue NewLD2 = DAG.getLoad(MVT::i32, DL, NewLD1.getValue(1), OffsetPtr,
+                                 LD->getPointerInfo(), LD->isVolatile(),
+                                 LD->isNonTemporal(),
+                                 std::min(4U, LD->getAlignment() / 2));
+
+    DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewLD2.getValue(1));
+    SDValue Result = DCI.CombineTo(N, NewLD1, NewLD2);
+    DCI.RemoveFromWorklist(LD);
+    DAG.DeleteNode(LD);
+    return Result;
+  }
+
   return SDValue();
 }
 

Added: llvm/trunk/test/CodeGen/ARM/fp-arg-shuffle.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fp-arg-shuffle.ll?rev=128759&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/fp-arg-shuffle.ll (added)
+++ llvm/trunk/test/CodeGen/ARM/fp-arg-shuffle.ll Fri Apr  1 21:40:43 2011
@@ -0,0 +1,11 @@
+; RUN: llc < %s -march=arm -mattr=+neon -float-abi=soft | FileCheck %s
+
+; CHECK: function1
+; CHECK-NOT: vmov r
+define double @function1(double %a, double %b, double %c, double %d, double %e, double %f) nounwind noinline ssp {
+entry:
+  %call = tail call double @function2(double %f, double %e, double %d, double %c, double %b, double %a) nounwind
+  ret double %call
+}
+
+declare double @function2(double, double, double, double, double, double)





More information about the llvm-commits mailing list