[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:
Ayke van Laethem 2021-03-03 14:23:31 +01:00
parent 13ca0c87ed
commit feda08b70a
No known key found for this signature in database
GPG Key ID: E97FF5335DFDFDED
4 changed files with 33 additions and 28 deletions

View File

@ -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

View File

@ -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]]

View File

@ -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

View File

@ -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]]