Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions llvm/lib/Target/ARM/ARMFrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2537,7 +2537,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
MachineRegisterInfo &MRI = MF.getRegInfo();
const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
(void)TRI; // Silence unused warning in non-assert builds.
Register FramePtr = RegInfo->getFrameRegister(MF);
Register FramePtr = STI.getFramePointerReg();
ARMSubtarget::PushPopSplitVariation PushPopSplit =
STI.getPushPopSplitVariation(MF);

Expand Down Expand Up @@ -2784,7 +2784,11 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
!CanEliminateFrame || RegInfo->cannotEliminateFrame(MF)) {
AFI->setHasStackFrame(true);

if (HasFP) {
// Save the FP if:
// 1. We currently need it (HasFP), OR
// 2. We might need it later due to stack realignment from aligned DPRCS2
// saves (which will make hasFP() become true in emitPrologue).
if (HasFP || (isFPReserved(MF) && AFI->getNumAlignedDPRCS2Regs() > 0)) {
SavedRegs.set(FramePtr);
// If the frame pointer is required by the ABI, also spill LR so that we
// emit a complete frame record.
Expand Down
37 changes: 37 additions & 0 deletions llvm/test/CodeGen/ARM/save-fp-with-non-leaf.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc %s -o - | FileCheck %s --check-prefix=CHECK
target datalayout = "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
target triple = "thumbv7-apple-darwin"

; This test checks that even with NEON register induced stack re-alignment, and
; with the frame-pointer=non-leaf option, that we still save fp aka r7 in the
; prolog as required.

define fastcc i32 @test_save_fp() #0 {
; CHECK-LABEL: test_save_fp:
; CHECK: @ %bb.0:
; CHECK-NEXT: push {r4, r7, lr}
; CHECK-NEXT: add r7, sp, #4
; CHECK-NEXT: sub.w r4, sp, #64
; CHECK-NEXT: bfc r4, #0, #4
; CHECK-NEXT: mov sp, r4
; CHECK-NEXT: vst1.64 {d8, d9, d10, d11}, [r4:128]!
; CHECK-NEXT: movs r0, #0
; CHECK-NEXT: vst1.64 {d12, d13, d14, d15}, [r4:128]
; CHECK-NEXT: mov r4, sp
; CHECK-NEXT: @ InlineAsm Start
; CHECK-NEXT: vld1.16 {d0, d1, d2, d3}, [r0]
; CHECK-NEXT: vld1.16 {d4, d5, d6, d7}, [r0]
; CHECK-NEXT: vabdl.s16 q4, d0, d4
; CHECK-EMPTY:
; CHECK-NEXT: @ InlineAsm End
; CHECK-NEXT: vld1.64 {d8, d9, d10, d11}, [r4:128]!
; CHECK-NEXT: vld1.64 {d12, d13, d14, d15}, [r4:128]
; CHECK-NEXT: subs r4, r7, #4
; CHECK-NEXT: mov sp, r4
; CHECK-NEXT: pop {r4, r7, pc}
tail call void asm sideeffect "vld1.i16 {q0,q1}, [$0]\0Avld1.i16 {q2,q3}, [$1]\0Avabdl.s16 q4, d0, d4\0A", "r,r,r,~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{memory}"(ptr null, ptr null, ptr null)
ret i32 0
}

attributes #0 = { "frame-pointer"="non-leaf" }
Loading