[AArch64] Exclude instructions after setting the FP from SEH prologues
authorMartin Storsjö <martin@martin.st>
Tue, 11 Oct 2022 12:11:39 +0000 (15:11 +0300)
committerMartin Storsjö <martin@martin.st>
Wed, 12 Oct 2022 09:36:21 +0000 (12:36 +0300)
After setting up the FP, the rest of the prologue doesn't need to
be replayed for unwinding the stack frame.

This allows reverting the functional parts of
2f7fbf837625267193351cc334e506a3a9161958 (but fixing inconsistent
duplicate setting of HasWinCFI).

Differential Revision: https://reviews.llvm.org/D135686

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
llvm/test/CodeGen/AArch64/wineh-align-stack.ll
llvm/test/CodeGen/AArch64/wineh-frame6.mir
llvm/test/CodeGen/AArch64/wineh-try-catch.ll

index b1776f0..e89ddf3 100644 (file)
@@ -1603,6 +1603,13 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
       emitFrameOffset(MBB, MBBI, DL, AArch64::FP, AArch64::SP,
                       StackOffset::getFixed(FPOffset), TII,
                       MachineInstr::FrameSetup, false, NeedsWinCFI, &HasWinCFI);
+      if (NeedsWinCFI && HasWinCFI) {
+        BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PrologEnd))
+            .setMIFlag(MachineInstr::FrameSetup);
+        // After setting up the FP, the rest of the prolog doesn't need to be
+        // included in the SEH unwind info.
+        NeedsWinCFI = false;
+      }
     }
     if (EmitCFI) {
       // Define the current CFA rule to use the provided FP.
index 638851c..1711820 100644 (file)
@@ -4335,6 +4335,8 @@ static void emitFrameOffsetAdj(MachineBasicBlock &MBB,
       int Imm = (int)(ThisVal << LocalShiftSize);
       if ((DestReg == AArch64::FP && SrcReg == AArch64::SP) ||
           (SrcReg == AArch64::FP && DestReg == AArch64::SP)) {
+        if (HasWinCFI)
+          *HasWinCFI = true;
         if (Imm == 0)
           BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_SetFP)).setMIFlag(Flag);
         else
@@ -4344,16 +4346,13 @@ static void emitFrameOffsetAdj(MachineBasicBlock &MBB,
         assert(Offset == 0 && "Expected remaining offset to be zero to "
                               "emit a single SEH directive");
       } else if (DestReg == AArch64::SP) {
+        if (HasWinCFI)
+          *HasWinCFI = true;
         assert(SrcReg == AArch64::SP && "Unexpected SrcReg for SEH_StackAlloc");
         BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_StackAlloc))
             .addImm(Imm)
             .setMIFlag(Flag);
-      } else {
-        BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
-            .setMIFlag(Flag);
       }
-      if (HasWinCFI)
-        *HasWinCFI = true;
     }
 
     SrcReg = TmpReg;
index 0b174a0..ddb0ab1 100644 (file)
@@ -17,11 +17,6 @@ declare dso_local void @other(ptr noundef)
 ; CHECK-NEXT: .seh_save_fplr_x 16
 ; CHECK-NEXT: mov x29, sp
 ; CHECK-NEXT: .seh_set_fp
+; CHECK-NEXT: .seh_endprologue
 ; CHECK-NEXT: sub x9, sp, #80
-; CHECK-NEXT: .seh_nop
 ; CHECK-NEXT: and sp, x9, #0xffffffffffffffe0
-; CHECK-NEXT: .seh_stackalloc 80
-; CHECK-NEXT: .seh_endprologue
-
-; FIXME: Ideally, the SEH prologue wouldn't include the stack realigning
-; instructions at all, but it's enough to end the prologue after .seh_set_fp.
index 535d805..913f122 100644 (file)
@@ -7,9 +7,8 @@
 # CHECK-NEXT: frame-setup SEH_SaveFPLR_X -16
 # CHECK-NEXT: $fp = frame-setup ADDXri $sp, 0, 0
 # CHECK-NEXT: frame-setup SEH_SetFP
-# CHECK-NEXT: $sp = frame-setup SUBXri $sp, 32, 0
-# CHECK-NEXT: frame-setup SEH_StackAlloc 32
 # CHECK-NEXT: frame-setup SEH_PrologEnd
+# CHECK-NEXT: $sp = frame-setup SUBXri $sp, 32, 0
 # CHECK:      frame-destroy SEH_EpilogStart
 # CHECK-NEXT: $sp = frame-destroy ADDXri $fp, 0, 0
 # CHECK-NEXT: frame-destroy SEH_SetFP
index 7de7d60..e60c7b9 100644 (file)
@@ -85,8 +85,6 @@
 
 ; UNWIND: Function: ?func@@YAHXZ (0x0)
 ; UNWIND: Prologue [
-; UNWIND-NEXT: ; nop
-; UNWIND-NEXT: ; sub sp, #624
 ; UNWIND-NEXT: ; add fp, sp, #32
 ; UNWIND-NEXT: ; stp x29, x30, [sp, #32]
 ; UNWIND-NEXT: ; str x28, [sp, #24]