Skip to content

Commit 40c937c

Browse files
committed
[ARM] Fix restoring stack for varargs with SEH split frame pointer push
Previously, the "add sp, rust-lang#12" ended up inserted after "bx lr". Differential Revision: https://reviews.llvm.org/D126872
1 parent 9f97720 commit 40c937c

File tree

2 files changed

+119
-1
lines changed

2 files changed

+119
-1
lines changed

llvm/lib/Target/ARM/ARMFrameLowering.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,9 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
13021302
MachineInstr::FrameDestroy);
13031303

13041304
// Increment past our save areas.
1305+
if (AFI->getGPRCalleeSavedArea2Size() && STI.splitFramePointerPush(MF))
1306+
MBBI++;
1307+
13051308
if (MBBI != MBB.end() && AFI->getDPRCalleeSavedAreaSize()) {
13061309
MBBI++;
13071310
// Since vpop register list cannot have gaps, there may be multiple vpop
@@ -1316,7 +1319,8 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
13161319
MachineInstr::FrameDestroy);
13171320
}
13181321

1319-
if (AFI->getGPRCalleeSavedArea2Size()) MBBI++;
1322+
if (AFI->getGPRCalleeSavedArea2Size() && !STI.splitFramePointerPush(MF))
1323+
MBBI++;
13201324
if (AFI->getGPRCalleeSavedArea1Size()) MBBI++;
13211325

13221326
if (ReservedArgStack || IncomingArgStackToRestore) {

llvm/test/CodeGen/ARM/Windows/wineh-framepointer.ll

+114
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,117 @@ declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
6060
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
6161

6262
declare arm_aapcs_vfpcc void @other(i32 noundef, ptr noundef, ptr noundef)
63+
64+
; CHECK-LABEL: everything_varargs:
65+
; CHECK-NEXT: .seh_proc everything_varargs
66+
; CHECK-NEXT: @ %bb.0: @ %entry
67+
; CHECK-NEXT: sub sp, #12
68+
; CHECK-NEXT: .seh_stackalloc 12
69+
; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, r9}
70+
; CHECK-NEXT: .seh_save_regs_w {r4-r9}
71+
; CHECK-NEXT: sub sp, #4
72+
; CHECK-NEXT: .seh_stackalloc 4
73+
; CHECK-NEXT: vpush {d8, d9, d10, d11, d12, d13, d14, d15}
74+
; CHECK-NEXT: .seh_save_fregs {d8-d15}
75+
; CHECK-NEXT: push.w {r11, lr}
76+
; CHECK-NEXT: .seh_save_regs_w {r11, lr}
77+
; CHECK-NEXT: mov r11, sp
78+
; CHECK-NEXT: .seh_save_sp r11
79+
; CHECK-NEXT: .seh_endprologue
80+
; CHECK-NEXT: movw r4, #1258
81+
; CHECK-NEXT: bl __chkstk
82+
; CHECK-NEXT: sub.w sp, sp, r4
83+
; CHECK-NEXT: mov r4, sp
84+
; CHECK-NEXT: bfc r4, #0, #4
85+
; CHECK-NEXT: mov sp, r4
86+
87+
; CHECK: .seh_startepilogue
88+
; CHECK-NEXT: mov sp, r11
89+
; CHECK-NEXT: .seh_save_sp r11
90+
; CHECK-NEXT: pop.w {r11, lr}
91+
; CHECK-NEXT: .seh_save_regs_w {r11, lr}
92+
; CHECK-NEXT: vpop {d8, d9, d10, d11, d12, d13, d14, d15}
93+
; CHECK-NEXT: .seh_save_fregs {d8-d15}
94+
; CHECK-NEXT: add sp, #4
95+
; CHECK-NEXT: .seh_stackalloc 4
96+
; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, r9}
97+
; CHECK-NEXT: .seh_save_regs_w {r4-r9}
98+
; CHECK-NEXT: add sp, #12
99+
; CHECK-NEXT: .seh_stackalloc 12
100+
; CHECK-NEXT: bx lr
101+
; CHECK-NEXT: .seh_nop
102+
; CHECK-NEXT: .seh_endepilogue
103+
; CHECK-NEXT: .seh_endproc
104+
105+
define arm_aapcs_vfpcc void @everything_varargs(i32 noundef %a, ...) {
106+
entry:
107+
%buf2 = alloca [5000 x i8], align 16
108+
%ap = alloca ptr, align 4
109+
%vla = alloca i8, i32 %a, align 1
110+
call void @llvm.lifetime.start.p0(i64 5000, ptr nonnull %buf2)
111+
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %ap)
112+
call void @llvm.va_start(ptr nonnull %ap)
113+
%0 = load ptr, ptr %ap, align 4
114+
call arm_aapcs_vfpcc void @other2(i32 noundef %a, ptr noundef nonnull %vla, ptr noundef nonnull %buf2, ptr noundef %0)
115+
call void @llvm.va_end(ptr nonnull %ap)
116+
call void asm sideeffect "", "~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r11},~{r12}"()
117+
call void asm sideeffect "", "~{d8},~{d9},~{d10},~{d11},~{d12},~{d13},~{d14},~{d15}"()
118+
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %ap)
119+
call void @llvm.lifetime.end.p0(i64 5000, ptr nonnull %buf2)
120+
ret void
121+
}
122+
123+
; CHECK-LABEL: novector_varargs:
124+
; CHECK-NEXT: .seh_proc novector_varargs
125+
; CHECK-NEXT: @ %bb.0: @ %entry
126+
; CHECK-NEXT: sub sp, #12
127+
; CHECK-NEXT: .seh_stackalloc 12
128+
; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, r9}
129+
; CHECK-NEXT: .seh_save_regs_w {r4-r9}
130+
; CHECK-NEXT: push.w {r11, lr}
131+
; CHECK-NEXT: .seh_save_regs_w {r11, lr}
132+
; CHECK-NEXT: mov r11, sp
133+
; CHECK-NEXT: .seh_save_sp r11
134+
; CHECK-NEXT: .seh_endprologue
135+
; CHECK-NEXT: movw r4, #1259
136+
; CHECK-NEXT: bl __chkstk
137+
; CHECK-NEXT: sub.w sp, sp, r4
138+
; CHECK-NEXT: mov r4, sp
139+
; CHECK-NEXT: bfc r4, #0, #4
140+
; CHECK-NEXT: mov sp, r4
141+
142+
; CHECK: .seh_startepilogue
143+
; CHECK-NEXT: mov sp, r11
144+
; CHECK-NEXT: .seh_save_sp r11
145+
; CHECK-NEXT: pop.w {r11, lr}
146+
; CHECK-NEXT: .seh_save_regs_w {r11, lr}
147+
; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, r9}
148+
; CHECK-NEXT: .seh_save_regs_w {r4-r9}
149+
; CHECK-NEXT: add sp, #12
150+
; CHECK-NEXT: .seh_stackalloc 12
151+
; CHECK-NEXT: bx lr
152+
; CHECK-NEXT: .seh_nop
153+
; CHECK-NEXT: .seh_endepilogue
154+
; CHECK-NEXT: .seh_endproc
155+
156+
define arm_aapcs_vfpcc void @novector_varargs(i32 noundef %a, ...) {
157+
entry:
158+
%buf2 = alloca [5000 x i8], align 16
159+
%ap = alloca ptr, align 4
160+
%vla = alloca i8, i32 %a, align 1
161+
call void @llvm.lifetime.start.p0(i64 5000, ptr nonnull %buf2)
162+
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %ap)
163+
call void @llvm.va_start(ptr nonnull %ap)
164+
%0 = load ptr, ptr %ap, align 4
165+
call arm_aapcs_vfpcc void @other2(i32 noundef %a, ptr noundef nonnull %vla, ptr noundef nonnull %buf2, ptr noundef %0)
166+
call void @llvm.va_end(ptr nonnull %ap)
167+
call void asm sideeffect "", "~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r11},~{r12}"()
168+
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %ap)
169+
call void @llvm.lifetime.end.p0(i64 5000, ptr nonnull %buf2)
170+
ret void
171+
}
172+
173+
declare void @llvm.va_start(ptr)
174+
declare void @llvm.va_end(ptr)
175+
176+
declare arm_aapcs_vfpcc void @other2(i32 noundef, ptr noundef, ptr noundef, ptr noundef)

0 commit comments

Comments
 (0)