From: Evan Cheng Date: Tue, 18 May 2010 21:31:17 +0000 (+0000) Subject: Sink dag combine's post index load / store code that swap base ptr and index into... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=28dad2a5caccf579f7430acd3af8fa6e6f8b575e;p=oota-llvm.git Sink dag combine's post index load / store code that swap base ptr and index into the target hook. Only the target knows whether the swap is safe. In Thumb2 mode, the offset must be an immediate. rdar://7998649 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104060 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d6e761f2bc3..bfa302cf095 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -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(Offset) && cast(Offset)->isNullValue()) diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index c284a7e0439..f5373cb0e7f 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -4407,9 +4407,11 @@ bool ARMTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, bool isSEXTLoad = false; if (LoadSDNode *LD = dyn_cast(N)) { VT = LD->getMemoryVT(); + Ptr = LD->getBasePtr(); isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD; } else if (StoreSDNode *ST = dyn_cast(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 index 00000000000..99072283c29 --- /dev/null +++ b/test/CodeGen/ARM/2010-05-18-PostIndexBug.ll @@ -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 ; [#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 ; [#uses=0] + unreachable + +bb.nph96: ; preds = %entry + unreachable +}