Skip to content

Commit 18f29a5

Browse files
authored
[ARM] Fix not saving FP when required to in frame-pointer=non-leaf. (#163699)
When the stars align to conspire against stack alignment, when we have frame-pointer=non-leaf we can incorrectly skip preserving fp/r7 in the prolog. The fix here first makes sure we're using the right frame pointer register in the context of preserving the incoming FP, and then make sure that we save the FP when re-alignment is known to be necessary. rdar://162462271
1 parent 196c2ec commit 18f29a5

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

llvm/lib/Target/ARM/ARMFrameLowering.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2536,7 +2536,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
25362536
MachineRegisterInfo &MRI = MF.getRegInfo();
25372537
const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
25382538
(void)TRI; // Silence unused warning in non-assert builds.
2539-
Register FramePtr = RegInfo->getFrameRegister(MF);
2539+
Register FramePtr = STI.getFramePointerReg();
25402540
ARMSubtarget::PushPopSplitVariation PushPopSplit =
25412541
STI.getPushPopSplitVariation(MF);
25422542

@@ -2783,7 +2783,11 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
27832783
!CanEliminateFrame || RegInfo->cannotEliminateFrame(MF)) {
27842784
AFI->setHasStackFrame(true);
27852785

2786-
if (HasFP) {
2786+
// Save the FP if:
2787+
// 1. We currently need it (HasFP), OR
2788+
// 2. We might need it later due to stack realignment from aligned DPRCS2
2789+
// saves (which will make hasFP() become true in emitPrologue).
2790+
if (HasFP || (isFPReserved(MF) && AFI->getNumAlignedDPRCS2Regs() > 0)) {
27872791
SavedRegs.set(FramePtr);
27882792
// If the frame pointer is required by the ABI, also spill LR so that we
27892793
// emit a complete frame record.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc %s -o - | FileCheck %s --check-prefix=CHECK
3+
target datalayout = "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
4+
target triple = "thumbv7-apple-darwin"
5+
6+
; This test checks that even with NEON register induced stack re-alignment, and
7+
; with the frame-pointer=non-leaf option, that we still save fp aka r7 in the
8+
; prolog as required.
9+
10+
define fastcc i32 @test_save_fp() #0 {
11+
; CHECK-LABEL: test_save_fp:
12+
; CHECK: @ %bb.0:
13+
; CHECK-NEXT: push {r4, r7, lr}
14+
; CHECK-NEXT: add r7, sp, #4
15+
; CHECK-NEXT: sub.w r4, sp, #64
16+
; CHECK-NEXT: bfc r4, #0, #4
17+
; CHECK-NEXT: mov sp, r4
18+
; CHECK-NEXT: vst1.64 {d8, d9, d10, d11}, [r4:128]!
19+
; CHECK-NEXT: movs r0, #0
20+
; CHECK-NEXT: vst1.64 {d12, d13, d14, d15}, [r4:128]
21+
; CHECK-NEXT: mov r4, sp
22+
; CHECK-NEXT: @ InlineAsm Start
23+
; CHECK-NEXT: vld1.16 {d0, d1, d2, d3}, [r0]
24+
; CHECK-NEXT: vld1.16 {d4, d5, d6, d7}, [r0]
25+
; CHECK-NEXT: vabdl.s16 q4, d0, d4
26+
; CHECK-EMPTY:
27+
; CHECK-NEXT: @ InlineAsm End
28+
; CHECK-NEXT: vld1.64 {d8, d9, d10, d11}, [r4:128]!
29+
; CHECK-NEXT: vld1.64 {d12, d13, d14, d15}, [r4:128]
30+
; CHECK-NEXT: subs r4, r7, #4
31+
; CHECK-NEXT: mov sp, r4
32+
; CHECK-NEXT: pop {r4, r7, pc}
33+
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)
34+
ret i32 0
35+
}
36+
37+
attributes #0 = { "frame-pointer"="non-leaf" }

0 commit comments

Comments
 (0)