diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp index 2703af7d73b9..3b1c843f035a 100644 --- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -322,24 +322,6 @@ static void emitAligningInstructions(MachineFunction &MF, ARMFunctionInfo *AFI, } } -/// We need the offset of the frame pointer relative to other MachineFrameInfo -/// offsets which are encoded relative to SP at function begin. -/// See also emitPrologue() for how the FP is set up. -/// Unfortunately we cannot determine this value in determineCalleeSaves() yet -/// as assignCalleeSavedSpillSlots() hasn't run at this point. Instead we use -/// this to produce a conservative estimate that we check in an assert() later. -static int getMaxFPOffset(const Function &F, const ARMFunctionInfo &AFI) { - // We may end up saving a lot of registers that are higher numbered than the - // r7 used for FP in thumb. - if (F.hasFnAttribute("interrupt") || - F.getCallingConv() == CallingConv::CXX_FAST_TLS) - return -AFI.getArgRegsSaveSize() - (8 * 4); - - // Usually it is just the link register and the FP itself (and in rare cases - // r12?) saved to reach FP. - return -AFI.getArgRegsSaveSize() - 12; -} - void ARMFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { MachineBasicBlock::iterator MBBI = MBB.begin(); @@ -450,10 +432,8 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF, unsigned DPRCSOffset = GPRCS2Offset - DPRGapSize - DPRCSSize; int FramePtrOffsetInPush = 0; if (HasFP) { - int FPOffset = MFI.getObjectOffset(FramePtrSpillFI); - assert(getMaxFPOffset(*MF.getFunction(), *AFI) <= FPOffset && - "Max FP estimation is wrong"); - FramePtrOffsetInPush = FPOffset + ArgRegsSaveSize; + FramePtrOffsetInPush = + MFI.getObjectOffset(FramePtrSpillFI) + ArgRegsSaveSize; AFI->setFramePtrSpillOffset(MFI.getObjectOffset(FramePtrSpillFI) + NumBytes); } @@ -1720,14 +1700,6 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, // worth the effort and added fragility? unsigned EstimatedStackSize = MFI.estimateStackSize(MF) + 4 * (NumGPRSpills + NumFPRSpills); - - // Determine biggest (positive) SP offset in MachineFrameInfo. - int MaxFixedOffset = 0; - for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) { - int MaxObjectOffset = MFI.getObjectOffset(I) + MFI.getObjectSize(I); - MaxFixedOffset = std::max(MaxFixedOffset, MaxObjectOffset); - } - bool HasFP = hasFP(MF); if (HasFP) { if (AFI->hasStackFrame()) @@ -1735,20 +1707,15 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, } else { // If FP is not used, SP will be used to access arguments, so count the // size of arguments into the estimation. - EstimatedStackSize += MaxFixedOffset; + EstimatedStackSize += AFI->getArgumentStackSize(); } EstimatedStackSize += 16; // For possible paddings. - unsigned EstimatedRSStackSizeLimit = estimateRSStackSizeLimit(MF, this); - int MaxFPOffset = getMaxFPOffset(*MF.getFunction(), *AFI); - bool BigFrameOffsets = EstimatedStackSize >= EstimatedRSStackSizeLimit || - MFI.hasVarSizedObjects() || - (MFI.adjustsStack() && !canSimplifyCallFramePseudos(MF)) || - // For large argument stacks fp relative addressed may overflow. - (HasFP && (MaxFixedOffset - MaxFPOffset) >= (int)EstimatedRSStackSizeLimit); + bool BigStack = EstimatedStackSize >= estimateRSStackSizeLimit(MF, this) || + MFI.hasVarSizedObjects() || + (MFI.adjustsStack() && !canSimplifyCallFramePseudos(MF)); bool ExtraCSSpill = false; - if (BigFrameOffsets || - !CanEliminateFrame || RegInfo->cannotEliminateFrame(MF)) { + if (BigStack || !CanEliminateFrame || RegInfo->cannotEliminateFrame(MF)) { AFI->setHasStackFrame(true); if (HasFP) { @@ -1932,7 +1899,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, // callee-saved register or reserve a special spill slot to facilitate // register scavenging. Thumb1 needs a spill slot for stack pointer // adjustments also, even when the frame itself is small. - if (BigFrameOffsets && !ExtraCSSpill) { + if (BigStack && !ExtraCSSpill) { // If any non-reserved CS register isn't spilled, just spill one or two // extra. That should take care of it! unsigned NumExtras = TargetAlign / 4; diff --git a/llvm/test/CodeGen/ARM/fpoffset_overflow.mir b/llvm/test/CodeGen/ARM/fpoffset_overflow.mir deleted file mode 100644 index 9c6cd931b153..000000000000 --- a/llvm/test/CodeGen/ARM/fpoffset_overflow.mir +++ /dev/null @@ -1,94 +0,0 @@ -# RUN: llc -o - %s -mtriple=thumbv7-- -run-pass=stack-protector -run-pass=prologepilog | FileCheck %s ---- -# This should trigger an emergency spill in the register scavenger because the -# frame offset into the large argument is too large. -# CHECK-LABEL: name: func0 -# CHECK: t2STRi12 killed %r7, %sp, 0, 14, _ :: (store 4 into %stack.0) -# CHECK: %r7 = t2ADDri killed %sp, 4096, 14, _, _ -# CHECK: %r11 = t2LDRi12 killed %r7, 36, 14, _ :: (load 4) -# CHECK: %r7 = t2LDRi12 %sp, 0, 14, _ :: (load 4 from %stack.0) -name: func0 -tracksRegLiveness: true -fixedStack: - - { id: 0, offset: 4084, size: 4, alignment: 4, isImmutable: true, - isAliased: false } - - { id: 1, offset: -12, size: 4096, alignment: 4, isImmutable: false, - isAliased: false } -body: | - bb.0: - %r0 = IMPLICIT_DEF - %r1 = IMPLICIT_DEF - %r2 = IMPLICIT_DEF - %r3 = IMPLICIT_DEF - %r4 = IMPLICIT_DEF - %r5 = IMPLICIT_DEF - %r6 = IMPLICIT_DEF - %r8 = IMPLICIT_DEF - %r9 = IMPLICIT_DEF - %r10 = IMPLICIT_DEF - %r11 = IMPLICIT_DEF - %r12 = IMPLICIT_DEF - %lr = IMPLICIT_DEF - - %r11 = t2LDRi12 %fixed-stack.0, 0, 14, _ :: (load 4) - - KILL %r0 - KILL %r1 - KILL %r2 - KILL %r3 - KILL %r4 - KILL %r5 - KILL %r6 - KILL %r8 - KILL %r9 - KILL %r10 - KILL %r11 - KILL %r12 - KILL %lr -... ---- -# This should not trigger an emergency spill yet. -# CHECK-LABEL: name: func1 -# CHECK-NOT: t2STRi12 -# CHECK-NOT: t2ADDri -# CHECK: %r11 = t2LDRi12 %sp, 4092, 14, _ :: (load 4) -# CHECK-NOT: t2LDRi12 -name: func1 -tracksRegLiveness: true -fixedStack: - - { id: 0, offset: 4044, size: 4, alignment: 4, isImmutable: true, - isAliased: false } - - { id: 1, offset: -12, size: 4056, alignment: 4, isImmutable: false, - isAliased: false } -body: | - bb.0: - %r0 = IMPLICIT_DEF - %r1 = IMPLICIT_DEF - %r2 = IMPLICIT_DEF - %r3 = IMPLICIT_DEF - %r4 = IMPLICIT_DEF - %r5 = IMPLICIT_DEF - %r6 = IMPLICIT_DEF - %r8 = IMPLICIT_DEF - %r9 = IMPLICIT_DEF - %r10 = IMPLICIT_DEF - %r11 = IMPLICIT_DEF - %r12 = IMPLICIT_DEF - %lr = IMPLICIT_DEF - - %r11 = t2LDRi12 %fixed-stack.0, 0, 14, _ :: (load 4) - - KILL %r0 - KILL %r1 - KILL %r2 - KILL %r3 - KILL %r4 - KILL %r5 - KILL %r6 - KILL %r8 - KILL %r9 - KILL %r10 - KILL %r11 - KILL %r12 - KILL %lr -...