diff --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp --- a/llvm/lib/Target/AVR/AVRISelLowering.cpp +++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp @@ -1313,15 +1313,17 @@ 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 MemOpChains; + for (; AI != AE; AI++) { + CCValAssign &VA = ArgLocs[AI]; + SDValue Arg = OutVals[AI]; assert(VA.isMemLoc()); @@ -1331,10 +1333,13 @@ 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 diff --git a/llvm/test/CodeGen/AVR/call.ll b/llvm/test/CodeGen/AVR/call.ll --- a/llvm/test/CodeGen/AVR/call.ll +++ b/llvm/test/CodeGen/AVR/call.ll @@ -52,14 +52,14 @@ 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_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_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]] diff --git a/llvm/test/CodeGen/AVR/dynalloca.ll b/llvm/test/CodeGen/AVR/dynalloca.ll --- a/llvm/test/CodeGen/AVR/dynalloca.ll +++ b/llvm/test/CodeGen/AVR/dynalloca.ll @@ -66,10 +66,10 @@ ; 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 diff --git a/llvm/test/CodeGen/AVR/varargs.ll b/llvm/test/CodeGen/AVR/varargs.ll --- a/llvm/test/CodeGen/AVR/varargs.ll +++ b/llvm/test/CodeGen/AVR/varargs.ll @@ -40,14 +40,14 @@ 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]]