aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Osborne <richard@xmos.com>2013-05-09 16:43:42 +0000
committerRichard Osborne <richard@xmos.com>2013-05-09 16:43:42 +0000
commit9bd913c4c1f350562b5a31e79a82dcaf143b06e0 (patch)
treeca26859c9bf1bc2ce13ec89da6450919c73c7224
parenta6ff92a975f2d6ef6a0db7aeaee3ee9fd046307a (diff)
downloadexternal_llvm-9bd913c4c1f350562b5a31e79a82dcaf143b06e0.zip
external_llvm-9bd913c4c1f350562b5a31e79a82dcaf143b06e0.tar.gz
external_llvm-9bd913c4c1f350562b5a31e79a82dcaf143b06e0.tar.bz2
[XCore] Fix handling of functions where only the LR is spilled.
Previously we only checked if the LR required saving if the frame size was non zero. However because the caller reserves 1 word for the callee to use that doesn't count towards our frame size it is possible for the LR to need saving and for the frame size to be 0. We didn't hit when the LR needed saving because of a function calls because the 1 word of stack we must allocate for our callee means the frame size is always non zero in this case. However we can hit this case if the LR is clobbered in inline asm. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181520 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/XCore/XCoreFrameLowering.cpp57
-rw-r--r--test/CodeGen/XCore/epilogue_prologue.ll11
2 files changed, 41 insertions, 27 deletions
diff --git a/lib/Target/XCore/XCoreFrameLowering.cpp b/lib/Target/XCore/XCoreFrameLowering.cpp
index beeb07f..8cd10b4 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<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo());
+ XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
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<XCoreFunctionInfo>();
+ 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 0000000..49a4cc7
--- /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
+}