mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-15 09:33:39 +00:00
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
This commit is contained in:
parent
011c3f110b
commit
28dad2a5ca
@ -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;
|
||||||
}
|
}
|
||||||
|
25
test/CodeGen/ARM/2010-05-18-PostIndexBug.ll
Normal file
25
test/CodeGen/ARM/2010-05-18-PostIndexBug.ll
Normal file
@ -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…
x
Reference in New Issue
Block a user