Sink dag combine's post index load / store code that swap base ptr and index into...
authorEvan Cheng <evan.cheng@apple.com>
Tue, 18 May 2010 21:31:17 +0000 (21:31 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Tue, 18 May 2010 21:31:17 +0000 (21:31 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104060 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
lib/Target/ARM/ARMISelLowering.cpp
test/CodeGen/ARM/2010-05-18-PostIndexBug.ll [new file with mode: 0644]

index d6e761f2bc3df59943a0a47bcaec9654f927dafb..bfa302cf09543633477f3469c9828c456c5d092a 100644 (file)
@@ -5284,10 +5284,6 @@ bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) {
     SDValue Offset;
     ISD::MemIndexedMode AM = ISD::UNINDEXED;
     if (TLI.getPostIndexedAddressParts(N, Op, BasePtr, Offset, AM, DAG)) {
-      if (Ptr == Offset && Op->getOpcode() == ISD::ADD)
-        std::swap(BasePtr, Offset);
-      if (Ptr != BasePtr)
-        continue;
       // Don't create a indexed load / store with zero offset.
       if (isa<ConstantSDNode>(Offset) &&
           cast<ConstantSDNode>(Offset)->isNullValue())
index c284a7e04396e6ab23dc3a21407b08ef8e85003a..f5373cb0e7f39b38c76bda100d0c45635097c2eb 100644 (file)
@@ -4407,9 +4407,11 @@ bool ARMTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
   bool isSEXTLoad = false;
   if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
     VT  = LD->getMemoryVT();
+    Ptr = LD->getBasePtr();
     isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
   } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
     VT  = ST->getMemoryVT();
+    Ptr = ST->getBasePtr();
   } else
     return false;
 
@@ -4417,13 +4419,25 @@ bool ARMTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
   bool isLegal = false;
   if (Subtarget->isThumb2())
     isLegal = getT2IndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
-                                        isInc, DAG);
+                                       isInc, DAG);
   else
     isLegal = getARMIndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
                                         isInc, DAG);
   if (!isLegal)
     return false;
 
+  if (Ptr != Base) {
+    // Swap base ptr and offset to catch more post-index load / store when
+    // it's legal. In Thumb2 mode, offset must be an immediate.
+    if (Ptr == Offset && Op->getOpcode() == ISD::ADD &&
+        !Subtarget->isThumb2())
+      std::swap(Base, Offset);
+
+    // Post-indexed load / store update the base pointer.
+    if (Ptr != Base)
+      return false;
+  }
+
   AM = isInc ? ISD::POST_INC : ISD::POST_DEC;
   return true;
 }
diff --git a/test/CodeGen/ARM/2010-05-18-PostIndexBug.ll b/test/CodeGen/ARM/2010-05-18-PostIndexBug.ll
new file mode 100644 (file)
index 0000000..9907228
--- /dev/null
@@ -0,0 +1,25 @@
+; RUN: llc < %s -mtriple=armv7-apple-darwin   | FileCheck %s -check-prefix=ARM
+; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s -check-prefix=THUMB
+; rdar://7998649
+
+%struct.foo = type { i64, i64 }
+
+define arm_apcscc zeroext i8 @t(%struct.foo* %this) noreturn optsize {
+entry:
+; ARM:       t:
+; ARM:       str r0, [r1], r0
+
+; THUMB:     t:
+; THUMB-NOT: str r0, [r1], r0
+; THUMB:     str r0, [r1]
+  %0 = getelementptr inbounds %struct.foo* %this, i32 0, i32 1 ; <i64*> [#uses=1]
+  store i32 undef, i32* inttoptr (i32 8 to i32*), align 8
+  br i1 undef, label %bb.nph96, label %bb3
+
+bb3:                                              ; preds = %entry
+  %1 = load i64* %0, align 4                      ; <i64> [#uses=0]
+  unreachable
+
+bb.nph96:                                         ; preds = %entry
+  unreachable
+}