From 1326c6f14bbd1e0b887320f30639cbab16cc1803 Mon Sep 17 00:00:00 2001 From: Robert Lytton Date: Mon, 2 Dec 2013 10:18:14 +0000 Subject: [PATCH] XCore target: Enable frames larger than 65535 to be lowered git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@196084 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/XCore/XCoreFrameLowering.cpp | 315 +++++++++++++----------- test/CodeGen/XCore/epilogue_prologue.ll | 125 ++++++++++ 2 files changed, 302 insertions(+), 138 deletions(-) diff --git a/lib/Target/XCore/XCoreFrameLowering.cpp b/lib/Target/XCore/XCoreFrameLowering.cpp index c34b35c140f..a436b6954ce 100644 --- a/lib/Target/XCore/XCoreFrameLowering.cpp +++ b/lib/Target/XCore/XCoreFrameLowering.cpp @@ -29,6 +29,9 @@ using namespace llvm; +static const unsigned FramePtr = XCore::R10; +static const int MaxImmU16 = (1<<16) - 1; + // helper functions. FIXME: Eliminate. static inline bool isImmU6(unsigned val) { return val < (1 << 6); @@ -38,34 +41,93 @@ static inline bool isImmU16(unsigned val) { return val < (1 << 16); } -static void loadFromStack(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, - unsigned DstReg, int Offset, DebugLoc dl, - const TargetInstrInfo &TII) { - assert(Offset%4 == 0 && "Misaligned stack offset"); - Offset/=4; - bool isU6 = isImmU6(Offset); - if (!isU6 && !isImmU16(Offset)) - report_fatal_error("loadFromStack offset too big " + Twine(Offset)); - int Opcode = isU6 ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; - BuildMI(MBB, I, dl, TII.get(Opcode), DstReg) - .addImm(Offset); +static void EmitDefCfaRegister(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, DebugLoc dl, + const TargetInstrInfo &TII, + MachineModuleInfo *MMI, unsigned DRegNum) { + MCSymbol *Label = MMI->getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(Label); + MMI->addFrameInst(MCCFIInstruction::createDefCfaRegister(Label, DRegNum)); +} + +static void EmitDefCfaOffset(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, DebugLoc dl, + const TargetInstrInfo &TII, + MachineModuleInfo *MMI, int Offset) { + MCSymbol *Label = MMI->getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(Label); + MMI->addFrameInst(MCCFIInstruction::createDefCfaOffset(Label, -Offset)); +} + +static void EmitCfiOffset(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, DebugLoc dl, + const TargetInstrInfo &TII, MachineModuleInfo *MMI, + unsigned DRegNum, int Offset, MCSymbol *Label) { + if (!Label) { + Label = MMI->getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(Label); + } + MMI->addFrameInst(MCCFIInstruction::createOffset(Label, DRegNum, Offset)); +} + +/// The SP register is moved in steps of 'MaxImmU16' towards the bottom of the +/// frame. During these steps, it may be necessary to spill registers. +/// IfNeededExtSP emits the necessary EXTSP instructions to move the SP only +/// as far as to make 'OffsetFromBottom' reachable using an STWSP_lru6. +/// \param OffsetFromTop the spill offset from the top of the frame. +/// \param [in] [out] Adjusted the current SP offset from the top of the frame. +static void IfNeededExtSP(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, DebugLoc dl, + const TargetInstrInfo &TII, MachineModuleInfo *MMI, + int OffsetFromTop, int &Adjusted, int FrameSize, + bool emitFrameMoves) { + while (OffsetFromTop > Adjusted) { + assert(Adjusted < FrameSize && "OffsetFromTop is beyond FrameSize"); + int remaining = FrameSize - Adjusted; + int OpImm = (remaining > MaxImmU16) ? MaxImmU16 : remaining; + int Opcode = isImmU6(OpImm) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; + BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(OpImm); + Adjusted += OpImm; + if (emitFrameMoves) + EmitDefCfaOffset(MBB, MBBI, dl, TII, MMI, Adjusted*4); + } } +/// The SP register is moved in steps of 'MaxImmU16' towards the top of the +/// frame. During these steps, it may be necessary to re-load registers. +/// IfNeededLDAWSP emits the necessary LDAWSP instructions to move the SP only +/// as far as to make 'OffsetFromTop' reachable using an LDAWSP_lru6. +/// \param OffsetFromTop the spill offset from the top of the frame. +/// \param [in] [out] RemainingAdj the current SP offset from the top of the frame. +static void IfNeededLDAWSP(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, DebugLoc dl, + const TargetInstrInfo &TII, int OffsetFromTop, + int &RemainingAdj) { + while (OffsetFromTop < RemainingAdj - MaxImmU16) { + assert(RemainingAdj && "OffsetFromTop is beyond FrameSize"); + int OpImm = (RemainingAdj > MaxImmU16) ? MaxImmU16 : RemainingAdj; + int Opcode = isImmU6(OpImm) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; + BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(OpImm); + RemainingAdj -= OpImm; + } +} -static void storeToStack(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, - unsigned SrcReg, int Offset, DebugLoc dl, - const TargetInstrInfo &TII) { - assert(Offset%4 == 0 && "Misaligned stack offset"); - Offset/=4; - bool isU6 = isImmU6(Offset); - if (!isU6 && !isImmU16(Offset)) - report_fatal_error("storeToStack offset too big " + Twine(Offset)); - int Opcode = isU6 ? XCore::STWSP_ru6 : XCore::STWSP_lru6; - BuildMI(MBB, I, dl, TII.get(Opcode)) - .addReg(SrcReg) - .addImm(Offset); +/// Creates an ordered list of registers that are spilled +/// during the emitPrologue/emitEpilogue. +/// Registers are ordered according to their frame offset. +static void GetSpillList(SmallVectorImpl > &SpillList, + MachineFrameInfo *MFI, XCoreFunctionInfo *XFI, + bool fetchLR, bool fetchFP) { + int LRSpillOffset = fetchLR? MFI->getObjectOffset(XFI->getLRSpillSlot()) : 0; + int FPSpillOffset = fetchFP? MFI->getObjectOffset(XFI->getFPSpillSlot()) : 0; + if (fetchLR && fetchFP && LRSpillOffset > FPSpillOffset) { + SpillList.push_back(std::make_pair(XCore::LR,LRSpillOffset)); + fetchLR = false; + } + if (fetchFP) + SpillList.push_back(std::make_pair(FramePtr, FPSpillOffset)); + if (fetchLR) + SpillList.push_back(std::make_pair(XCore::LR,LRSpillOffset)); } @@ -80,7 +142,7 @@ XCoreFrameLowering::XCoreFrameLowering(const XCoreSubtarget &sti) bool XCoreFrameLowering::hasFP(const MachineFunction &MF) const { return MF.getTarget().Options.DisableFramePointerElim(MF) || - MF.getFrameInfo()->hasVarSizedObjects(); + MF.getFrameInfo()->hasVarSizedObjects(); } void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { @@ -98,90 +160,69 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { report_fatal_error("emitPrologue unsupported alignment: " + Twine(MFI->getMaxAlignment())); - bool FP = hasFP(MF); const AttributeSet &PAL = MF.getFunction()->getAttributes(); - if (PAL.hasAttrSomewhere(Attribute::Nest)) - loadFromStack(MBB, MBBI, XCore::R11, 0, dl, TII); + BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0); // Work out frame sizes. - int FrameSize = MFI->getStackSize(); - assert(FrameSize%4 == 0 && "Misaligned frame size"); - FrameSize/=4; - - bool isU6 = isImmU6(FrameSize); - - if (!isU6 && !isImmU16(FrameSize)) { - // FIXME could emit multiple instructions. - report_fatal_error("emitPrologue Frame size too big: " + Twine(FrameSize)); - } - bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF); + // We will adjust the SP in stages towards the final FrameSize. + assert(MFI->getStackSize()%4 == 0 && "Misaligned frame size"); + const int FrameSize = MFI->getStackSize() / 4; + int Adjusted = 0; bool saveLR = XFI->getUsesLR(); - // Do we need to allocate space on the stack? - if (FrameSize) { - bool LRSavedOnEntry = false; - int Opcode; - if (saveLR && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0)) { - Opcode = (isU6) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6; - MBB.addLiveIn(XCore::LR); - saveLR = false; - LRSavedOnEntry = true; - } else { - Opcode = (isU6) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; - } - BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); + bool UseENTSP = saveLR && FrameSize + && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0); + if (UseENTSP) + saveLR = false; + bool FP = hasFP(MF); + bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF); + if (UseENTSP) { + // Allocate space on the stack at the same time as saving LR. + Adjusted = (FrameSize > MaxImmU16) ? MaxImmU16 : FrameSize; + int Opcode = isImmU6(Adjusted) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6; + BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(Adjusted); + MBB.addLiveIn(XCore::LR); if (emitFrameMoves) { - // Show update of SP. - MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol(); - BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(FrameLabel); - MMI->addFrameInst(MCCFIInstruction::createDefCfaOffset(FrameLabel, - -FrameSize*4)); - if (LRSavedOnEntry) { - unsigned Reg = MRI->getDwarfRegNum(XCore::LR, true); - MMI->addFrameInst(MCCFIInstruction::createOffset(FrameLabel, Reg, 0)); - } + EmitDefCfaOffset(MBB, MBBI, dl, TII, MMI, Adjusted*4); + unsigned DRegNum = MRI->getDwarfRegNum(XCore::LR, true); + EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, 0, NULL); } } - if (saveLR) { - int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); - storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4, dl, TII); - MBB.addLiveIn(XCore::LR); + // If necessary, save LR and FP to the stack, as we EXTSP. + SmallVector,2> SpillList; + GetSpillList(SpillList, MFI, XFI, saveLR, FP); + for (unsigned i = 0, e = SpillList.size(); i != e; ++i) { + unsigned SpillReg = SpillList[i].first; + int SpillOffset = SpillList[i].second; + assert(SpillOffset % 4 == 0 && "Misaligned stack offset"); + assert(SpillOffset <= 0 && "Unexpected positive stack offset"); + int OffsetFromTop = - SpillOffset/4; + IfNeededExtSP(MBB, MBBI, dl, TII, MMI, OffsetFromTop, Adjusted, FrameSize, + emitFrameMoves); + int Offset = Adjusted - OffsetFromTop; + int Opcode = isImmU6(Offset) ? XCore::STWSP_ru6 : XCore::STWSP_lru6; + BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addReg(SpillReg).addImm(Offset); + MBB.addLiveIn(SpillReg); if (emitFrameMoves) { - MCSymbol *SaveLRLabel = MMI->getContext().CreateTempSymbol(); - BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(SaveLRLabel); - unsigned Reg = MRI->getDwarfRegNum(XCore::LR, true); - MMI->addFrameInst(MCCFIInstruction::createOffset(SaveLRLabel, Reg, - LRSpillOffset)); + unsigned DRegNum = MRI->getDwarfRegNum(SpillReg, true); + EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, SpillOffset, NULL); } } + // Complete any remaining Stack adjustment. + IfNeededExtSP(MBB, MBBI, dl, TII, MMI, FrameSize, Adjusted, FrameSize, + emitFrameMoves); + assert(Adjusted==FrameSize && "IfNeededExtSP has not completed adjustment"); + if (FP) { - // Save R10 to the stack. - int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); - storeToStack(MBB, MBBI, XCore::R10, FPSpillOffset + FrameSize*4, dl, TII); - // R10 is live-in. It is killed at the spill. - MBB.addLiveIn(XCore::R10); - if (emitFrameMoves) { - MCSymbol *SaveR10Label = MMI->getContext().CreateTempSymbol(); - BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(SaveR10Label); - unsigned Reg = MRI->getDwarfRegNum(XCore::R10, true); - MMI->addFrameInst(MCCFIInstruction::createOffset(SaveR10Label, Reg, - FPSpillOffset)); - } // Set the FP from the SP. - unsigned FramePtr = XCore::R10; BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0); - if (emitFrameMoves) { - // Show FP is now valid. - MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol(); - BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(FrameLabel); - unsigned Reg = MRI->getDwarfRegNum(FramePtr, true); - MMI->addFrameInst(MCCFIInstruction::createDefCfaRegister(FrameLabel, - Reg)); - } + if (emitFrameMoves) + EmitDefCfaRegister(MBB, MBBI, dl, TII, MMI, + MRI->getDwarfRegNum(FramePtr, true)); } if (emitFrameMoves) { @@ -192,9 +233,8 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { MCSymbol *SpillLabel = SpillLabels[I].first; CalleeSavedInfo &CSI = SpillLabels[I].second; int Offset = MFI->getObjectOffset(CSI.getFrameIdx()); - unsigned Reg = MRI->getDwarfRegNum(CSI.getReg(), true); - MMI->addFrameInst(MCCFIInstruction::createOffset(SpillLabel, Reg, - Offset)); + unsigned DRegNum = MRI->getDwarfRegNum(CSI.getReg(), true); + EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, Offset, SpillLabel); } } } @@ -208,60 +248,58 @@ void XCoreFrameLowering::emitEpilogue(MachineFunction &MF, XCoreFunctionInfo *XFI = MF.getInfo(); DebugLoc dl = MBBI->getDebugLoc(); - bool FP = hasFP(MF); - if (FP) { - // Restore the stack pointer. - unsigned FramePtr = XCore::R10; - BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)) - .addReg(FramePtr); - } - // Work out frame sizes. - int FrameSize = MFI->getStackSize(); - - assert(FrameSize%4 == 0 && "Misaligned frame size"); - - FrameSize/=4; - - bool isU6 = isImmU6(FrameSize); - - if (!isU6 && !isImmU16(FrameSize)) { - // FIXME could emit multiple instructions. - report_fatal_error("emitEpilogue Frame size too big: " + Twine(FrameSize)); - } - - if (FP) { - // Restore R10 - int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); - FPSpillOffset += FrameSize*4; - loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset, dl, TII); - } + // We will adjust the SP in stages towards the final FrameSize. + int RemainingAdj = MFI->getStackSize(); + assert(RemainingAdj%4 == 0 && "Misaligned frame size"); + RemainingAdj /= 4; 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); + bool UseRETSP = restoreLR && RemainingAdj + && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0); + if (UseRETSP) restoreLR = false; + bool FP = hasFP(MF); + + if (FP) // Restore the stack pointer. + BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr); + + // If necessary, restore LR and FP from the stack, as we EXTSP. + SmallVector,2> SpillList; + GetSpillList(SpillList, MFI, XFI, restoreLR, FP); + unsigned i = SpillList.size(); + while (i--) { + unsigned SpilledReg = SpillList[i].first; + int SpillOffset = SpillList[i].second; + assert(SpillOffset % 4 == 0 && "Misaligned stack offset"); + assert(SpillOffset <= 0 && "Unexpected positive stack offset"); + int OffsetFromTop = - SpillOffset/4; + IfNeededLDAWSP(MBB, MBBI, dl, TII, OffsetFromTop, RemainingAdj); + int Offset = RemainingAdj - OffsetFromTop; + int Opcode = isImmU6(Offset) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; + BuildMI(MBB, MBBI, dl, TII.get(Opcode), SpilledReg).addImm(Offset); } - if (FrameSize) { - if (restoreLR) { + if (RemainingAdj) { + // Complete all but one of the remaining Stack adjustments. + IfNeededLDAWSP(MBB, MBBI, dl, TII, 0, RemainingAdj); + if (UseRETSP) { // 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; - MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); + || MBBI->getOpcode() == XCore::RETSP_lu6); + int Opcode = isImmU6(RemainingAdj) ? XCore::RETSP_u6 : XCore::RETSP_lu6; + MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode)) + .addImm(RemainingAdj); for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i) MIB->addOperand(MBBI->getOperand(i)); // copy any variadic operands - MBB.erase(MBBI); + MBB.erase(MBBI); // Erase the previous return instruction. } else { - int Opcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; - BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(FrameSize); + int Opcode = isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 : + XCore::LDAWSP_lru6; + BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(RemainingAdj); + // Don't erase the return instruction. } - } + } // else Don't erase the return instruction. } bool XCoreFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, @@ -278,7 +316,8 @@ bool XCoreFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF); DebugLoc DL; - if (MI != MBB.end()) DL = MI->getDebugLoc(); + if (MI != MBB.end()) + DL = MI->getDebugLoc(); for (std::vector::const_iterator it = CSI.begin(); it != CSI.end(); ++it) { diff --git a/test/CodeGen/XCore/epilogue_prologue.ll b/test/CodeGen/XCore/epilogue_prologue.ll index 185565f4e28..ffbe7a1571f 100644 --- a/test/CodeGen/XCore/epilogue_prologue.ll +++ b/test/CodeGen/XCore/epilogue_prologue.ll @@ -1,5 +1,15 @@ ; RUN: llc < %s -march=xcore | FileCheck %s +; RUN: llc < %s -march=xcore -disable-fp-elim | FileCheck %s -check-prefix=CHECKFP + +; CHECKFP-LABEL: f1 +; CHECKFP: entsp 2 +; CHECKFP-NEXT: stw r10, sp[1] +; CHECKFP-NEXT: ldaw r10, sp[0] +; CHECKFP: set sp, r10 +; CHECKFP-NEXT: ldw r10, sp[1] +; CHECKFP-NEXT: retsp 2 +; ; CHECK-LABEL: f1 ; CHECK: stw lr, sp[0] ; CHECK: ldw lr, sp[0] @@ -10,6 +20,22 @@ entry: ret void } + +; CHECKFP-LABEL:f3 +; CHECKFP: entsp 3 +; CHECKFP-NEXT: stw r10, sp[1] +; CHECKFP-NEXT: ldaw r10, sp[0] +; CHECKFP-NEXT: stw [[REG:r[4-9]+]], r10[2] +; CHECKFP-NEXT: mov [[REG]], r0 +; CHECKFP-NEXT: extsp 1 +; CHECKFP-NEXT: bl f2 +; CHECKFP-NEXT: ldaw sp, sp[1] +; CHECKFP-NEXT: mov r0, [[REG]] +; CHECKFP-NEXT: ldw [[REG]], r10[2] +; CHECKFP-NEXT: set sp, r10 +; CHECKFP-NEXT: ldw r10, sp[1] +; CHECKFP-NEXT: retsp 3 +; ; CHECK-LABEL: f3 ; CHECK: entsp 2 ; CHECK: stw [[REG:r[4-9]+]], sp[1] @@ -24,3 +50,102 @@ entry: call void @f2() ret i32 %i } + + +; CHECKFP-LABEL: f4 +; CHECKFP: extsp 65535 +; CHECKFP-NEXT: .Ltmp{{[0-9]+}} +; CHECKFP-NEXT: .cfi_def_cfa_offset 262140 +; CHECKFP-NEXT: extsp 34467 +; CHECKFP-NEXT: .Ltmp{{[0-9]+}} +; CHECKFP-NEXT: .cfi_def_cfa_offset 400008 +; CHECKFP-NEXT: stw r10, sp[1] +; CHECKFP-NEXT: .Ltmp{{[0-9]+}} +; CHECKFP-NEXT: .cfi_offset 10, -400004 +; CHECKFP-NEXT: ldaw r10, sp[0] +; CHECKFP-NEXT: .Ltmp{{[0-9]+}} +; CHECKFP-NEXT: .cfi_def_cfa_register 10 +; CHECKFP-NEXT: set sp, r10 +; CHECKFP-NEXT: ldw r10, sp[1] +; CHECKFP-NEXT: ldaw sp, sp[65535] +; CHECKFP-NEXT: ldaw sp, sp[34467] +; CHECKFP-NEXT: retsp 0 +; +; CHECK-LABEL: f4 +; CHECK: extsp 65535 +; CHECK-NEXT: .Ltmp{{[0-9]+}} +; CHECK-NEXT: .cfi_def_cfa_offset 262140 +; CHECK-NEXT: extsp 34465 +; CHECK-NEXT: .Ltmp{{[0-9]+}} +; CHECK-NEXT: .cfi_def_cfa_offset 400000 +; CHECK-NEXT: ldaw sp, sp[65535] +; CHECK-NEXT: ldaw sp, sp[34465] +; CHECK-NEXT: retsp 0 +define void @f4() { +entry: + %0 = alloca [100000 x i32], align 4 + ret void +} + + +; CHECKFP-LABEL: f6 +; CHECKFP: entsp 65535 +; CHECKFP-NEXT: .Ltmp{{[0-9]+}} +; CHECKFP-NEXT: .cfi_def_cfa_offset 262140 +; CHECKFP-NEXT: .Ltmp{{[0-9]+}} +; CHECKFP-NEXT: .cfi_offset 15, 0 +; CHECKFP-NEXT: extsp 65535 +; CHECKFP-NEXT: .Ltmp{{[0-9]+}} +; CHECKFP-NEXT: .cfi_def_cfa_offset 524280 +; CHECKFP-NEXT: extsp 65535 +; CHECKFP-NEXT: .Ltmp{{[0-9]+}} +; CHECKFP-NEXT: .cfi_def_cfa_offset 786420 +; CHECKFP-NEXT: extsp 3396 +; CHECKFP-NEXT: .Ltmp{{[0-9]+}} +; CHECKFP-NEXT: .cfi_def_cfa_offset 800004 +; CHECKFP-NEXT: stw r10, sp[1] +; CHECKFP-NEXT: .Ltmp{{[0-9]+}} +; CHECKFP-NEXT: .cfi_offset 10, -800000 +; CHECKFP-NEXT: ldaw r10, sp[0] +; CHECKFP-NEXT: .Ltmp{{[0-9]+}} +; CHECKFP-NEXT: .cfi_def_cfa_register 10 +; CHECKFP-NEXT: extsp 1 +; CHECKFP-NEXT: ldaw r0, r10[2] +; CHECKFP-NEXT: bl f5 +; CHECKFP-NEXT: ldaw sp, sp[1] +; CHECKFP-NEXT: set sp, r10 +; CHECKFP-NEXT: ldw r10, sp[1] +; CHECKFP-NEXT: ldaw sp, sp[65535] +; CHECKFP-NEXT: ldaw sp, sp[65535] +; CHECKFP-NEXT: ldaw sp, sp[65535] +; CHECKFP-NEXT: retsp 3396 +; +; CHECK-LABEL: f6 +; CHECK: entsp 65535 +; CHECK-NEXT: .Ltmp{{[0-9]+}} +; CHECK-NEXT: .cfi_def_cfa_offset 262140 +; CHECK-NEXT: .Ltmp{{[0-9]+}} +; CHECK-NEXT: .cfi_offset 15, 0 +; CHECK-NEXT: extsp 65535 +; CHECK-NEXT: .Ltmp{{[0-9]+}} +; CHECK-NEXT: .cfi_def_cfa_offset 524280 +; CHECK-NEXT: extsp 65535 +; CHECK-NEXT: .Ltmp{{[0-9]+}} +; CHECK-NEXT: .cfi_def_cfa_offset 786420 +; CHECK-NEXT: extsp 3395 +; CHECK-NEXT: .Ltmp{{[0-9]+}} +; CHECK-NEXT: .cfi_def_cfa_offset 800000 +; CHECK-NEXT: ldaw r0, sp[1] +; CHECK-NEXT: bl f5 +; CHECK-NEXT: ldaw sp, sp[65535] +; CHECK-NEXT: ldaw sp, sp[65535] +; CHECK-NEXT: ldaw sp, sp[65535] +; CHECK-NEXT: retsp 3395 +declare void @f5(i32*) +define void @f6() { +entry: + %0 = alloca [199999 x i32], align 4 + %1 = getelementptr inbounds [199999 x i32]* %0, i32 0, i32 0 + call void @f5(i32* %1) + ret void +} -- 2.34.1