diff --git a/lib/Target/XCore/XCoreFrameLowering.cpp b/lib/Target/XCore/XCoreFrameLowering.cpp index beeb07f831c..8cd10b4e743 100644 --- a/lib/Target/XCore/XCoreFrameLowering.cpp +++ b/lib/Target/XCore/XCoreFrameLowering.cpp @@ -116,9 +116,9 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { } bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF); + bool saveLR = XFI->getUsesLR(); // Do we need to allocate space on the stack? if (FrameSize) { - bool saveLR = XFI->getUsesLR(); bool LRSavedOnEntry = false; int Opcode; if (saveLR && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0)) { @@ -148,18 +148,18 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { Moves.push_back(MachineMove(FrameLabel, CSDst, CSSrc)); } } - if (saveLR) { - int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); - storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4, dl, TII); - MBB.addLiveIn(XCore::LR); + } + if (saveLR) { + int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); + storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4, dl, TII); + MBB.addLiveIn(XCore::LR); - if (emitFrameMoves) { - MCSymbol *SaveLRLabel = MMI->getContext().CreateTempSymbol(); - BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(SaveLRLabel); - MachineLocation CSDst(MachineLocation::VirtualFP, LRSpillOffset); - MachineLocation CSSrc(XCore::LR); - MMI->getFrameMoves().push_back(MachineMove(SaveLRLabel, CSDst, CSSrc)); - } + if (emitFrameMoves) { + MCSymbol *SaveLRLabel = MMI->getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(SaveLRLabel); + MachineLocation CSDst(MachineLocation::VirtualFP, LRSpillOffset); + MachineLocation CSSrc(XCore::LR); + MMI->getFrameMoves().push_back(MachineMove(SaveLRLabel, CSDst, CSSrc)); } } @@ -213,6 +213,7 @@ void XCoreFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); const XCoreInstrInfo &TII = *static_cast(MF.getTarget().getInstrInfo()); + XCoreFunctionInfo *XFI = MF.getInfo(); DebugLoc dl = MBBI->getDebugLoc(); bool FP = hasFP(MF); @@ -237,24 +238,26 @@ void XCoreFrameLowering::emitEpilogue(MachineFunction &MF, report_fatal_error("emitEpilogue Frame size too big: " + Twine(FrameSize)); } - if (FrameSize) { - XCoreFunctionInfo *XFI = MF.getInfo(); + if (FP) { + // Restore R10 + int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); + FPSpillOffset += FrameSize*4; + loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset, dl, TII); + } - if (FP) { - // Restore R10 - int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); - FPSpillOffset += FrameSize*4; - loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset, dl, TII); - } - bool restoreLR = XFI->getUsesLR(); - if (restoreLR && MFI->getObjectOffset(XFI->getLRSpillSlot()) != 0) { - int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); - LRSpillOffset += FrameSize*4; - loadFromStack(MBB, MBBI, XCore::LR, LRSpillOffset, dl, TII); - restoreLR = false; - } + bool restoreLR = XFI->getUsesLR(); + if (restoreLR && + (FrameSize == 0 || MFI->getObjectOffset(XFI->getLRSpillSlot()) != 0)) { + int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); + LRSpillOffset += FrameSize*4; + loadFromStack(MBB, MBBI, XCore::LR, LRSpillOffset, dl, TII); + restoreLR = false; + } + + if (FrameSize) { if (restoreLR) { // Fold prologue into return instruction + assert(MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0); assert(MBBI->getOpcode() == XCore::RETSP_u6 || MBBI->getOpcode() == XCore::RETSP_lu6); int Opcode = (isU6) ? XCore::RETSP_u6 : XCore::RETSP_lu6; diff --git a/test/CodeGen/XCore/epilogue_prologue.ll b/test/CodeGen/XCore/epilogue_prologue.ll new file mode 100644 index 00000000000..49a4cc79ac2 --- /dev/null +++ b/test/CodeGen/XCore/epilogue_prologue.ll @@ -0,0 +1,11 @@ +; RUN: llc < %s -march=xcore | FileCheck %s + +; CHECK: f1 +; CHECK: stw lr, sp[0] +; CHECK: ldw lr, sp[0] +; CHECK-NEXT: retsp 0 +define void @f1() nounwind { +entry: + tail call void asm sideeffect "", "~{lr}"() nounwind + ret void +}