forked from OSchip/llvm-project
[AVR] Do not chain stores in call frame setup
Previously, AVRTargetLowering::LowerCall attempted to keep stack stores in order with chains. Perhaps this worked in the past, but it does not work now: it appears that the SelectionDAG legalization phase removes these chains. Therefore, I've removed these chains entirely to match X86 (which, similar to AVR, also prefers to use push instructions over stack-relative stores to set up a call frame). With this change, all the stack stores are in a somewhat reasonable order. Differential Revision: https://reviews.llvm.org/D97853
This commit is contained in:
parent
13ca0c87ed
commit
feda08b70a
|
@ -1323,15 +1323,17 @@ SDValue AVRTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
|||
RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
|
||||
}
|
||||
|
||||
// Second, stack arguments have to walked in reverse order by inserting
|
||||
// chained stores, this ensures their order is not changed by the scheduler
|
||||
// and that the push instruction sequence generated is correct, otherwise they
|
||||
// can be freely intermixed.
|
||||
// Second, stack arguments have to walked.
|
||||
// Previously this code created chained stores but those chained stores appear
|
||||
// to be unchained in the legalization phase. Therefore, do not attempt to
|
||||
// chain them here. In fact, chaining them here somehow causes the first and
|
||||
// second store to be reversed which is the exact opposite of the intended
|
||||
// effect.
|
||||
if (HasStackArgs) {
|
||||
for (AE = AI, AI = ArgLocs.size(); AI != AE; --AI) {
|
||||
unsigned Loc = AI - 1;
|
||||
CCValAssign &VA = ArgLocs[Loc];
|
||||
SDValue Arg = OutVals[Loc];
|
||||
SmallVector<SDValue, 8> MemOpChains;
|
||||
for (; AI != AE; AI++) {
|
||||
CCValAssign &VA = ArgLocs[AI];
|
||||
SDValue Arg = OutVals[AI];
|
||||
|
||||
assert(VA.isMemLoc());
|
||||
|
||||
|
@ -1341,10 +1343,13 @@ SDValue AVRTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
|||
DAG.getRegister(AVR::SP, getPointerTy(DAG.getDataLayout())),
|
||||
DAG.getIntPtrConstant(VA.getLocMemOffset() + 1, DL));
|
||||
|
||||
Chain =
|
||||
MemOpChains.push_back(
|
||||
DAG.getStore(Chain, DL, Arg, PtrOff,
|
||||
MachinePointerInfo::getStack(MF, VA.getLocMemOffset()));
|
||||
MachinePointerInfo::getStack(MF, VA.getLocMemOffset())));
|
||||
}
|
||||
|
||||
if (!MemOpChains.empty())
|
||||
Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
|
||||
}
|
||||
|
||||
// Build a sequence of copy-to-reg nodes chained together with token chain and
|
||||
|
|
|
@ -52,14 +52,14 @@ define i16 @calli16_reg() {
|
|||
|
||||
define i16 @calli16_stack() {
|
||||
; CHECK-LABEL: calli16_stack:
|
||||
; CHECK: ldi [[REG1:r[0-9]+]], 9
|
||||
; CHECK: ldi [[REG2:r[0-9]+]], 2
|
||||
; CHECK: std Z+1, [[REG1]]
|
||||
; CHECK: std Z+2, [[REG2]]
|
||||
; CHECK: ldi [[REG1:r[0-9]+]], 10
|
||||
; CHECK: ldi [[REG2:r[0-9]+]], 2
|
||||
; CHECK: std Z+3, [[REG1]]
|
||||
; CHECK: std Z+4, [[REG2]]
|
||||
; CHECK: ldi [[REG1:r[0-9]+]], 9
|
||||
; CHECK: ldi [[REG2:r[0-9]+]], 2
|
||||
; CHECK: std Z+1, [[REG1]]
|
||||
; CHECK: std Z+2, [[REG2]]
|
||||
; CHECK: call foo16_2
|
||||
%result1 = call i16 @foo16_2(i16 512, i16 513, i16 514, i16 515, i16 516, i16 517, i16 518, i16 519, i16 520, i16 521, i16 522)
|
||||
ret i16 %result1
|
||||
|
@ -82,14 +82,14 @@ define i32 @calli32_reg() {
|
|||
|
||||
define i32 @calli32_stack() {
|
||||
; CHECK-LABEL: calli32_stack:
|
||||
; CHECK: ldi [[REG1:r[0-9]+]], 64
|
||||
; CHECK: ldi [[REG2:r[0-9]+]], 66
|
||||
; CHECK: std Z+1, [[REG1]]
|
||||
; CHECK: std Z+2, [[REG2]]
|
||||
; CHECK: ldi [[REG1:r[0-9]+]], 15
|
||||
; CHECK: ldi [[REG2:r[0-9]+]], 2
|
||||
; CHECK: std Z+3, [[REG1]]
|
||||
; CHECK: std Z+4, [[REG2]]
|
||||
; CHECK: ldi [[REG1:r[0-9]+]], 64
|
||||
; CHECK: ldi [[REG2:r[0-9]+]], 66
|
||||
; CHECK: std Z+1, [[REG1]]
|
||||
; CHECK: std Z+2, [[REG2]]
|
||||
; CHECK: call foo32_2
|
||||
%result1 = call i32 @foo32_2(i32 1, i32 2, i32 3, i32 4, i32 34554432)
|
||||
ret i32 %result1
|
||||
|
@ -113,14 +113,14 @@ define i64 @calli64_reg() {
|
|||
define i64 @calli64_stack() {
|
||||
; CHECK-LABEL: calli64_stack:
|
||||
|
||||
; CHECK: ldi [[REG1:r[0-9]+]], 76
|
||||
; CHECK: ldi [[REG2:r[0-9]+]], 73
|
||||
; CHECK: std Z+5, [[REG1]]
|
||||
; CHECK: std Z+6, [[REG2]]
|
||||
; CHECK: ldi [[REG1:r[0-9]+]], 31
|
||||
; CHECK: ldi [[REG2:r[0-9]+]], 242
|
||||
; CHECK: std Z+7, [[REG1]]
|
||||
; CHECK: std Z+8, [[REG2]]
|
||||
; CHECK: ldi [[REG1:r[0-9]+]], 76
|
||||
; CHECK: ldi [[REG2:r[0-9]+]], 73
|
||||
; CHECK: std Z+5, [[REG1]]
|
||||
; CHECK: std Z+6, [[REG2]]
|
||||
; CHECK: ldi [[REG1:r[0-9]+]], 155
|
||||
; CHECK: ldi [[REG2:r[0-9]+]], 88
|
||||
; CHECK: std Z+3, [[REG1]]
|
||||
|
|
|
@ -66,10 +66,10 @@ define void @dynalloca2(i16 %x) {
|
|||
; Store values on the stack
|
||||
; CHECK: ldi r16, 0
|
||||
; CHECK: ldi r17, 0
|
||||
; CHECK: std Z+5, r16
|
||||
; CHECK: std Z+6, r17
|
||||
; CHECK: std Z+7, r16
|
||||
; CHECK: std Z+8, r17
|
||||
; CHECK: std Z+5, r16
|
||||
; CHECK: std Z+6, r17
|
||||
; CHECK: std Z+3, r16
|
||||
; CHECK: std Z+4, r17
|
||||
; CHECK: std Z+1, r16
|
||||
|
|
|
@ -40,14 +40,14 @@ define i16 @varargs2(i8* nocapture %x, ...) {
|
|||
declare void @var1223(i16, ...)
|
||||
define void @varargcall() {
|
||||
; CHECK-LABEL: varargcall:
|
||||
; CHECK: ldi [[REG1:r[0-9]+]], 189
|
||||
; CHECK: ldi [[REG2:r[0-9]+]], 205
|
||||
; CHECK: std Z+3, [[REG1]]
|
||||
; CHECK: std Z+4, [[REG2]]
|
||||
; CHECK: ldi [[REG1:r[0-9]+]], 191
|
||||
; CHECK: ldi [[REG2:r[0-9]+]], 223
|
||||
; CHECK: std Z+5, [[REG1]]
|
||||
; CHECK: std Z+6, [[REG2]]
|
||||
; CHECK: ldi [[REG1:r[0-9]+]], 189
|
||||
; CHECK: ldi [[REG2:r[0-9]+]], 205
|
||||
; CHECK: std Z+3, [[REG1]]
|
||||
; CHECK: std Z+4, [[REG2]]
|
||||
; CHECK: ldi [[REG1:r[0-9]+]], 205
|
||||
; CHECK: ldi [[REG2:r[0-9]+]], 171
|
||||
; CHECK: std Z+1, [[REG1]]
|
||||
|
|
Loading…
Reference in New Issue