forked from OSchip/llvm-project
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
llvm-svn: 104060
This commit is contained in:
parent
feedc90c57
commit
f19384d54a
|
@ -5284,10 +5284,6 @@ bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) {
|
||||||
SDValue Offset;
|
SDValue Offset;
|
||||||
ISD::MemIndexedMode AM = ISD::UNINDEXED;
|
ISD::MemIndexedMode AM = ISD::UNINDEXED;
|
||||||
if (TLI.getPostIndexedAddressParts(N, Op, BasePtr, Offset, AM, DAG)) {
|
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.
|
// Don't create a indexed load / store with zero offset.
|
||||||
if (isa<ConstantSDNode>(Offset) &&
|
if (isa<ConstantSDNode>(Offset) &&
|
||||||
cast<ConstantSDNode>(Offset)->isNullValue())
|
cast<ConstantSDNode>(Offset)->isNullValue())
|
||||||
|
|
|
@ -4407,9 +4407,11 @@ bool ARMTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
|
||||||
bool isSEXTLoad = false;
|
bool isSEXTLoad = false;
|
||||||
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
|
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
|
||||||
VT = LD->getMemoryVT();
|
VT = LD->getMemoryVT();
|
||||||
|
Ptr = LD->getBasePtr();
|
||||||
isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
|
isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
|
||||||
} else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
|
} else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
|
||||||
VT = ST->getMemoryVT();
|
VT = ST->getMemoryVT();
|
||||||
|
Ptr = ST->getBasePtr();
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -4417,13 +4419,25 @@ bool ARMTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
|
||||||
bool isLegal = false;
|
bool isLegal = false;
|
||||||
if (Subtarget->isThumb2())
|
if (Subtarget->isThumb2())
|
||||||
isLegal = getT2IndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
|
isLegal = getT2IndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
|
||||||
isInc, DAG);
|
isInc, DAG);
|
||||||
else
|
else
|
||||||
isLegal = getARMIndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
|
isLegal = getARMIndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
|
||||||
isInc, DAG);
|
isInc, DAG);
|
||||||
if (!isLegal)
|
if (!isLegal)
|
||||||
return false;
|
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;
|
AM = isInc ? ISD::POST_INC : ISD::POST_DEC;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue