Skip to content

Commit 2d9c6e6

Browse files
committed
[Thumb1] Use callee-saved register to adjust stack pointer
When adjusting the Stack Pointer at the end of the function epilogue, use a callee-saved register, rather than explicitly using R4 which may not have been saved. Differential Revision: https://reviews.llvm.org/D157500
1 parent c86a0dd commit 2d9c6e6

File tree

8 files changed

+67
-58
lines changed

8 files changed

+67
-58
lines changed

llvm/lib/Target/ARM/Thumb1FrameLowering.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -538,18 +538,30 @@ void Thumb1FrameLowering::emitEpilogue(MachineFunction &MF,
538538
AFI->getDPRCalleeSavedAreaSize() +
539539
ArgRegsSaveSize);
540540

541+
// We are likely to need a scratch register and we know all callee-save
542+
// registers are free at this point in the epilogue, so pick one.
543+
unsigned ScratchRegister = ARM::NoRegister;
544+
bool HasFP = hasFP(MF);
545+
for (auto &I : MFI.getCalleeSavedInfo()) {
546+
Register Reg = I.getReg();
547+
if (isARMLowRegister(Reg) && !(HasFP && Reg == FramePtr)) {
548+
ScratchRegister = Reg;
549+
break;
550+
}
551+
}
552+
541553
if (AFI->shouldRestoreSPFromFP()) {
542554
NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
543555
// Reset SP based on frame pointer only if the stack frame extends beyond
544556
// frame pointer stack slot, the target is ELF and the function has FP, or
545557
// the target uses var sized objects.
546558
if (NumBytes) {
547-
assert(!MFI.getPristineRegs(MF).test(ARM::R4) &&
559+
assert(ScratchRegister != ARM::NoRegister &&
548560
"No scratch register to restore SP from FP!");
549-
emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::R4, FramePtr, -NumBytes,
561+
emitThumbRegPlusImmediate(MBB, MBBI, dl, ScratchRegister, FramePtr, -NumBytes,
550562
TII, *RegInfo, MachineInstr::FrameDestroy);
551563
BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::SP)
552-
.addReg(ARM::R4)
564+
.addReg(ScratchRegister)
553565
.add(predOps(ARMCC::AL))
554566
.setMIFlag(MachineInstr::FrameDestroy);
555567
} else
@@ -558,18 +570,6 @@ void Thumb1FrameLowering::emitEpilogue(MachineFunction &MF,
558570
.add(predOps(ARMCC::AL))
559571
.setMIFlag(MachineInstr::FrameDestroy);
560572
} else {
561-
// For a large stack frame, we might need a scratch register to store
562-
// the size of the frame. We know all callee-save registers are free
563-
// at this point in the epilogue, so pick one.
564-
unsigned ScratchRegister = ARM::NoRegister;
565-
bool HasFP = hasFP(MF);
566-
for (auto &I : MFI.getCalleeSavedInfo()) {
567-
Register Reg = I.getReg();
568-
if (isARMLowRegister(Reg) && !(HasFP && Reg == FramePtr)) {
569-
ScratchRegister = Reg;
570-
break;
571-
}
572-
}
573573
if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tBX_RET &&
574574
&MBB.front() != &*MBBI && std::prev(MBBI)->getOpcode() == ARM::tPOP) {
575575
MachineBasicBlock::iterator PMBBI = std::prev(MBBI);

llvm/test/CodeGen/ARM/cmse.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,9 @@ define void @func5() #4 {
290290
; CHECK-8B-NEXT: mov sp, r4
291291
; CHECK-8B-NEXT: mov r0, sp
292292
; CHECK-8B-NEXT: bl func51
293-
; CHECK-8B-NEXT: subs r4, r7, #7
294-
; CHECK-8B-NEXT: subs r4, #1
295-
; CHECK-8B-NEXT: mov sp, r4
293+
; CHECK-8B-NEXT: subs r6, r7, #7
294+
; CHECK-8B-NEXT: subs r6, #1
295+
; CHECK-8B-NEXT: mov sp, r6
296296
; CHECK-8B-NEXT: pop {r4, r6, r7}
297297
; CHECK-8B-NEXT: pop {r0}
298298
; CHECK-8B-NEXT: mov lr, r0

llvm/test/CodeGen/ARM/thumb1-varalloc.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ bb2:
3333

3434
bb3:
3535
%.0 = phi ptr [ %0, %entry ], [ %5, %bb2 ], [ %2, %bb1 ]
36-
; CHECK: subs r4, r7, #7
37-
; CHECK-NEXT: subs r4, #1
38-
; CHECK-NEXT: mov sp, r4
36+
; CHECK: subs r6, r7, #7
37+
; CHECK-NEXT: subs r6, #1
38+
; CHECK-NEXT: mov sp, r6
3939
; CHECK-NEXT: pop {r4, r6, r7, pc}
4040
ret ptr %.0
4141
}

llvm/test/CodeGen/Thumb/2011-EpilogueBug.ll

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@
55
%struct.info = type { i32, i32, i32, i32, i32, i32, i32, ptr }
66

77
define void @t1(ptr %v) {
8-
; CHECK: push {r4
98
%tmp6 = load i32, ptr null
109
%tmp8 = alloca float, i32 %tmp6
1110
store i32 1, ptr null
1211
br label %return
1312

1413
return: ; preds = %0
15-
; CHECK: mov sp, r4
14+
; CHECK: subs [[SCRATCH:r[0-7]]], r7, #7
15+
; CHECK: subs [[SCRATCH]], #1
16+
; CHECK: mov sp, [[SCRATCH]]
17+
; CHECK-NEXT: pop
18+
; CHECK-SAME: [[SCRATCH]]
1619
ret void
1720
}

llvm/test/CodeGen/Thumb/callee_save.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -304,9 +304,9 @@ define <4 x i32> @base_pointer(i32 %a) {
304304
; CHECK-NEXT: movs r1, #2
305305
; CHECK-NEXT: movs r2, #3
306306
; CHECK-NEXT: movs r3, #4
307-
; CHECK-NEXT: subs r4, r7, #7
308-
; CHECK-NEXT: subs r4, #9
309-
; CHECK-NEXT: mov sp, r4
307+
; CHECK-NEXT: subs r6, r7, #7
308+
; CHECK-NEXT: subs r6, #9
309+
; CHECK-NEXT: mov sp, r6
310310
; CHECK-NEXT: pop {r4, r6}
311311
; CHECK-NEXT: mov r8, r4
312312
; CHECK-NEXT: mov r9, r6

llvm/test/CodeGen/Thumb/emergency-spill-slot.ll

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ define void @vla_emergency_spill(i32 %n) {
2929
; CHECK-NEXT: ldr r0, [r6]
3030
; CHECK-NEXT: @APP
3131
; CHECK-NEXT: @NO_APP
32-
; CHECK-NEXT: subs r4, r7, #7
33-
; CHECK-NEXT: subs r4, #5
34-
; CHECK-NEXT: mov sp, r4
32+
; CHECK-NEXT: subs r6, r7, #7
33+
; CHECK-NEXT: subs r6, #5
34+
; CHECK-NEXT: mov sp, r6
3535
; CHECK-NEXT: pop {r4, r5, r6, r7, pc}
3636
; CHECK-NEXT: .p2align 2
3737
; CHECK-NEXT: @ %bb.1:
@@ -253,9 +253,9 @@ define void @aligned_emergency_spill(i32 %n, i32 %n2, i32 %n3, i32 %n4, ptr byva
253253
; CHECK-NEXT: ldr r0, [sp]
254254
; CHECK-NEXT: @APP
255255
; CHECK-NEXT: @NO_APP
256-
; CHECK-NEXT: subs r4, r7, #7
257-
; CHECK-NEXT: subs r4, #5
258-
; CHECK-NEXT: mov sp, r4
256+
; CHECK-NEXT: subs r6, r7, #7
257+
; CHECK-NEXT: subs r6, #5
258+
; CHECK-NEXT: mov sp, r6
259259
; CHECK-NEXT: pop {r4, r5, r6, r7, pc}
260260
; CHECK-NEXT: .p2align 2
261261
; CHECK-NEXT: @ %bb.1:
@@ -300,9 +300,9 @@ define void @aligned_no_emergency_spill(i32 %n, i32 %n2, i32 %n3, i32 %n4, ptr b
300300
; CHECK-NEXT: str r5, [r7, #124]
301301
; CHECK-NEXT: @APP
302302
; CHECK-NEXT: @NO_APP
303-
; CHECK-NEXT: subs r4, r7, #7
304-
; CHECK-NEXT: subs r4, #5
305-
; CHECK-NEXT: mov sp, r4
303+
; CHECK-NEXT: subs r6, r7, #7
304+
; CHECK-NEXT: subs r6, #5
305+
; CHECK-NEXT: mov sp, r6
306306
; CHECK-NEXT: pop {r4, r5, r6, r7, pc}
307307
entry:
308308
%y = alloca [4 x i32], align 16
@@ -350,9 +350,9 @@ define void @aligned_out_of_range_access(i32 %n, i32 %n2, i32 %n3, i32 %n4, ptr
350350
; CHECK-NEXT: ldr r0, [sp, #8] @ 4-byte Reload
351351
; CHECK-NEXT: @APP
352352
; CHECK-NEXT: @NO_APP
353-
; CHECK-NEXT: subs r4, r7, #7
354-
; CHECK-NEXT: subs r4, #5
355-
; CHECK-NEXT: mov sp, r4
353+
; CHECK-NEXT: subs r6, r7, #7
354+
; CHECK-NEXT: subs r6, #5
355+
; CHECK-NEXT: mov sp, r6
356356
; CHECK-NEXT: pop {r4, r5, r6, r7, pc}
357357
entry:
358358
%y = alloca [4 x i32], align 16

llvm/test/CodeGen/Thumb/frame-chain.ll

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,9 @@ define dso_local void @required_fp(i32 %0, i32 %1) {
151151
; FP-NEXT: movs r1, #0
152152
; FP-NEXT: str r1, [r6, #4]
153153
; FP-NEXT: str r0, [r2]
154-
; FP-NEXT: subs r4, r7, #7
155-
; FP-NEXT: subs r4, #1
156-
; FP-NEXT: mov sp, r4
154+
; FP-NEXT: subs r6, r7, #7
155+
; FP-NEXT: subs r6, #1
156+
; FP-NEXT: mov sp, r6
157157
; FP-NEXT: pop {r4, r6, r7, pc}
158158
;
159159
; FP-AAPCS-LABEL: required_fp:
@@ -185,9 +185,9 @@ define dso_local void @required_fp(i32 %0, i32 %1) {
185185
; FP-AAPCS-NEXT: movs r1, #0
186186
; FP-AAPCS-NEXT: str r1, [r6, #4]
187187
; FP-AAPCS-NEXT: str r0, [r2]
188-
; FP-AAPCS-NEXT: mov r4, r11
189-
; FP-AAPCS-NEXT: subs r4, #8
190-
; FP-AAPCS-NEXT: mov sp, r4
188+
; FP-AAPCS-NEXT: mov r6, r11
189+
; FP-AAPCS-NEXT: subs r6, #8
190+
; FP-AAPCS-NEXT: mov sp, r6
191191
; FP-AAPCS-NEXT: pop {r4, r6}
192192
; FP-AAPCS-NEXT: pop {r0}
193193
; FP-AAPCS-NEXT: mov r11, r0
@@ -217,9 +217,9 @@ define dso_local void @required_fp(i32 %0, i32 %1) {
217217
; NOFP-NEXT: movs r1, #0
218218
; NOFP-NEXT: str r1, [r6, #4]
219219
; NOFP-NEXT: str r0, [r2]
220-
; NOFP-NEXT: subs r4, r7, #7
221-
; NOFP-NEXT: subs r4, #1
222-
; NOFP-NEXT: mov sp, r4
220+
; NOFP-NEXT: subs r6, r7, #7
221+
; NOFP-NEXT: subs r6, #1
222+
; NOFP-NEXT: mov sp, r6
223223
; NOFP-NEXT: pop {r4, r6, r7, pc}
224224
;
225225
; NOFP-AAPCS-LABEL: required_fp:
@@ -251,9 +251,9 @@ define dso_local void @required_fp(i32 %0, i32 %1) {
251251
; NOFP-AAPCS-NEXT: movs r1, #0
252252
; NOFP-AAPCS-NEXT: str r1, [r6, #4]
253253
; NOFP-AAPCS-NEXT: str r0, [r2]
254-
; NOFP-AAPCS-NEXT: mov r4, r11
255-
; NOFP-AAPCS-NEXT: subs r4, #8
256-
; NOFP-AAPCS-NEXT: mov sp, r4
254+
; NOFP-AAPCS-NEXT: mov r6, r11
255+
; NOFP-AAPCS-NEXT: subs r6, #8
256+
; NOFP-AAPCS-NEXT: mov sp, r6
257257
; NOFP-AAPCS-NEXT: pop {r4, r6}
258258
; NOFP-AAPCS-NEXT: pop {r0}
259259
; NOFP-AAPCS-NEXT: mov r11, r0

llvm/test/CodeGen/Thumb/large-stack.ll

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@ define void @test100_nofpelim() "frame-pointer"="all" {
3333
; CHECK: sub sp, #508
3434
; CHECK: sub sp, #508
3535
; CHECK: sub sp, #508
36-
; CHECK: subs r4, r7, #7
37-
; CHECK: subs r4, #1
38-
; CHECK: mov sp, r4
36+
; CHECK: subs [[SCRATCH:r[0-7]]], r7, #7
37+
; CHECK: subs [[SCRATCH]], #1
38+
; CHECK: mov sp, [[SCRATCH]]
39+
; CHECK: pop
40+
; CHECK-SAME: [[SCRATCH]]
3941
%tmp = alloca [ 1524 x i8 ] , align 4
4042
ret void
4143
}
@@ -56,9 +58,11 @@ define void @test2_nofpelim() "frame-pointer"="all" {
5658
; CHECK-LABEL: test2_nofpelim{{>?}}:
5759
; CHECK: ldr [[TEMP:r[0-7]]],
5860
; CHECK: add sp, [[TEMP]]
59-
; CHECK: subs r4, r7, #7
60-
; CHECK: subs r4, #1
61-
; CHECK: mov sp, r4
61+
; CHECK: subs [[SCRATCH:r[0-7]]], r7, #7
62+
; CHECK: subs [[SCRATCH]], #1
63+
; CHECK: mov sp, [[SCRATCH]]
64+
; CHECK: pop
65+
; CHECK-SAME: [[SCRATCH]]
6266
%tmp = alloca [ 1528 x i8 ] , align 4
6367
ret void
6468
}
@@ -85,8 +89,10 @@ define i32 @test3_nofpelim() "frame-pointer"="all" {
8589
; CHECK: add sp, [[TEMP]]
8690
; CHECK: ldr [[TEMP2:r[0-7]]],
8791
; CHECK: add [[TEMP2]], sp
88-
; CHECK: subs r4, r7,
89-
; CHECK: mov sp, r4
92+
; CHECK: subs [[SCRATCH:r[0-7]]], r7,
93+
; CHECK: mov sp, [[SCRATCH]]
94+
; CHECK: pop
95+
; CHECK-SAME: [[SCRATCH]]
9096
%retval = alloca i32, align 4
9197
%tmp = alloca i32, align 4
9298
%a = alloca [805306369 x i8], align 8

0 commit comments

Comments
 (0)