forked from OSchip/llvm-project
[ARM] Fix restoring stack for varargs with SEH split frame pointer push
Previously, the "add sp, #12" ended up inserted after "bx lr". Differential Revision: https://reviews.llvm.org/D126872
This commit is contained in:
parent
9f97720268
commit
40c937cba2
|
@ -1302,6 +1302,9 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
|
|||
MachineInstr::FrameDestroy);
|
||||
|
||||
// Increment past our save areas.
|
||||
if (AFI->getGPRCalleeSavedArea2Size() && STI.splitFramePointerPush(MF))
|
||||
MBBI++;
|
||||
|
||||
if (MBBI != MBB.end() && AFI->getDPRCalleeSavedAreaSize()) {
|
||||
MBBI++;
|
||||
// Since vpop register list cannot have gaps, there may be multiple vpop
|
||||
|
@ -1316,7 +1319,8 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
|
|||
MachineInstr::FrameDestroy);
|
||||
}
|
||||
|
||||
if (AFI->getGPRCalleeSavedArea2Size()) MBBI++;
|
||||
if (AFI->getGPRCalleeSavedArea2Size() && !STI.splitFramePointerPush(MF))
|
||||
MBBI++;
|
||||
if (AFI->getGPRCalleeSavedArea1Size()) MBBI++;
|
||||
|
||||
if (ReservedArgStack || IncomingArgStackToRestore) {
|
||||
|
|
|
@ -60,3 +60,117 @@ declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
|
|||
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
|
||||
|
||||
declare arm_aapcs_vfpcc void @other(i32 noundef, ptr noundef, ptr noundef)
|
||||
|
||||
; CHECK-LABEL: everything_varargs:
|
||||
; CHECK-NEXT: .seh_proc everything_varargs
|
||||
; CHECK-NEXT: @ %bb.0: @ %entry
|
||||
; CHECK-NEXT: sub sp, #12
|
||||
; CHECK-NEXT: .seh_stackalloc 12
|
||||
; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, r9}
|
||||
; CHECK-NEXT: .seh_save_regs_w {r4-r9}
|
||||
; CHECK-NEXT: sub sp, #4
|
||||
; CHECK-NEXT: .seh_stackalloc 4
|
||||
; CHECK-NEXT: vpush {d8, d9, d10, d11, d12, d13, d14, d15}
|
||||
; CHECK-NEXT: .seh_save_fregs {d8-d15}
|
||||
; CHECK-NEXT: push.w {r11, lr}
|
||||
; CHECK-NEXT: .seh_save_regs_w {r11, lr}
|
||||
; CHECK-NEXT: mov r11, sp
|
||||
; CHECK-NEXT: .seh_save_sp r11
|
||||
; CHECK-NEXT: .seh_endprologue
|
||||
; CHECK-NEXT: movw r4, #1258
|
||||
; CHECK-NEXT: bl __chkstk
|
||||
; CHECK-NEXT: sub.w sp, sp, r4
|
||||
; CHECK-NEXT: mov r4, sp
|
||||
; CHECK-NEXT: bfc r4, #0, #4
|
||||
; CHECK-NEXT: mov sp, r4
|
||||
|
||||
; CHECK: .seh_startepilogue
|
||||
; CHECK-NEXT: mov sp, r11
|
||||
; CHECK-NEXT: .seh_save_sp r11
|
||||
; CHECK-NEXT: pop.w {r11, lr}
|
||||
; CHECK-NEXT: .seh_save_regs_w {r11, lr}
|
||||
; CHECK-NEXT: vpop {d8, d9, d10, d11, d12, d13, d14, d15}
|
||||
; CHECK-NEXT: .seh_save_fregs {d8-d15}
|
||||
; CHECK-NEXT: add sp, #4
|
||||
; CHECK-NEXT: .seh_stackalloc 4
|
||||
; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, r9}
|
||||
; CHECK-NEXT: .seh_save_regs_w {r4-r9}
|
||||
; CHECK-NEXT: add sp, #12
|
||||
; CHECK-NEXT: .seh_stackalloc 12
|
||||
; CHECK-NEXT: bx lr
|
||||
; CHECK-NEXT: .seh_nop
|
||||
; CHECK-NEXT: .seh_endepilogue
|
||||
; CHECK-NEXT: .seh_endproc
|
||||
|
||||
define arm_aapcs_vfpcc void @everything_varargs(i32 noundef %a, ...) {
|
||||
entry:
|
||||
%buf2 = alloca [5000 x i8], align 16
|
||||
%ap = alloca ptr, align 4
|
||||
%vla = alloca i8, i32 %a, align 1
|
||||
call void @llvm.lifetime.start.p0(i64 5000, ptr nonnull %buf2)
|
||||
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %ap)
|
||||
call void @llvm.va_start(ptr nonnull %ap)
|
||||
%0 = load ptr, ptr %ap, align 4
|
||||
call arm_aapcs_vfpcc void @other2(i32 noundef %a, ptr noundef nonnull %vla, ptr noundef nonnull %buf2, ptr noundef %0)
|
||||
call void @llvm.va_end(ptr nonnull %ap)
|
||||
call void asm sideeffect "", "~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r11},~{r12}"()
|
||||
call void asm sideeffect "", "~{d8},~{d9},~{d10},~{d11},~{d12},~{d13},~{d14},~{d15}"()
|
||||
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %ap)
|
||||
call void @llvm.lifetime.end.p0(i64 5000, ptr nonnull %buf2)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: novector_varargs:
|
||||
; CHECK-NEXT: .seh_proc novector_varargs
|
||||
; CHECK-NEXT: @ %bb.0: @ %entry
|
||||
; CHECK-NEXT: sub sp, #12
|
||||
; CHECK-NEXT: .seh_stackalloc 12
|
||||
; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, r9}
|
||||
; CHECK-NEXT: .seh_save_regs_w {r4-r9}
|
||||
; CHECK-NEXT: push.w {r11, lr}
|
||||
; CHECK-NEXT: .seh_save_regs_w {r11, lr}
|
||||
; CHECK-NEXT: mov r11, sp
|
||||
; CHECK-NEXT: .seh_save_sp r11
|
||||
; CHECK-NEXT: .seh_endprologue
|
||||
; CHECK-NEXT: movw r4, #1259
|
||||
; CHECK-NEXT: bl __chkstk
|
||||
; CHECK-NEXT: sub.w sp, sp, r4
|
||||
; CHECK-NEXT: mov r4, sp
|
||||
; CHECK-NEXT: bfc r4, #0, #4
|
||||
; CHECK-NEXT: mov sp, r4
|
||||
|
||||
; CHECK: .seh_startepilogue
|
||||
; CHECK-NEXT: mov sp, r11
|
||||
; CHECK-NEXT: .seh_save_sp r11
|
||||
; CHECK-NEXT: pop.w {r11, lr}
|
||||
; CHECK-NEXT: .seh_save_regs_w {r11, lr}
|
||||
; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, r9}
|
||||
; CHECK-NEXT: .seh_save_regs_w {r4-r9}
|
||||
; CHECK-NEXT: add sp, #12
|
||||
; CHECK-NEXT: .seh_stackalloc 12
|
||||
; CHECK-NEXT: bx lr
|
||||
; CHECK-NEXT: .seh_nop
|
||||
; CHECK-NEXT: .seh_endepilogue
|
||||
; CHECK-NEXT: .seh_endproc
|
||||
|
||||
define arm_aapcs_vfpcc void @novector_varargs(i32 noundef %a, ...) {
|
||||
entry:
|
||||
%buf2 = alloca [5000 x i8], align 16
|
||||
%ap = alloca ptr, align 4
|
||||
%vla = alloca i8, i32 %a, align 1
|
||||
call void @llvm.lifetime.start.p0(i64 5000, ptr nonnull %buf2)
|
||||
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %ap)
|
||||
call void @llvm.va_start(ptr nonnull %ap)
|
||||
%0 = load ptr, ptr %ap, align 4
|
||||
call arm_aapcs_vfpcc void @other2(i32 noundef %a, ptr noundef nonnull %vla, ptr noundef nonnull %buf2, ptr noundef %0)
|
||||
call void @llvm.va_end(ptr nonnull %ap)
|
||||
call void asm sideeffect "", "~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r11},~{r12}"()
|
||||
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %ap)
|
||||
call void @llvm.lifetime.end.p0(i64 5000, ptr nonnull %buf2)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.va_start(ptr)
|
||||
declare void @llvm.va_end(ptr)
|
||||
|
||||
declare arm_aapcs_vfpcc void @other2(i32 noundef, ptr noundef, ptr noundef, ptr noundef)
|
||||
|
|
Loading…
Reference in New Issue