[llvm] 40c937c - [ARM] Fix restoring stack for varargs with SEH split frame pointer push

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 2 23:45:48 PDT 2022


Author: Martin Storsjö
Date: 2022-06-03T09:32:00+03:00
New Revision: 40c937cba239db817b53d47c4525a751a8c488a0

URL: https://github.com/llvm/llvm-project/commit/40c937cba239db817b53d47c4525a751a8c488a0
DIFF: https://github.com/llvm/llvm-project/commit/40c937cba239db817b53d47c4525a751a8c488a0.diff

LOG: [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

Added: 
    

Modified: 
    llvm/lib/Target/ARM/ARMFrameLowering.cpp
    llvm/test/CodeGen/ARM/Windows/wineh-framepointer.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
index 0916df31ac956..bb3e2478842d3 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -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) {

diff  --git a/llvm/test/CodeGen/ARM/Windows/wineh-framepointer.ll b/llvm/test/CodeGen/ARM/Windows/wineh-framepointer.ll
index 6b9a8a9b05209..17197006d8261 100644
--- a/llvm/test/CodeGen/ARM/Windows/wineh-framepointer.ll
+++ b/llvm/test/CodeGen/ARM/Windows/wineh-framepointer.ll
@@ -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)


        


More information about the llvm-commits mailing list