diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -1603,6 +1603,13 @@ 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. diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -4335,6 +4335,8 @@ 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 @@ 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; diff --git a/llvm/test/CodeGen/AArch64/wineh-align-stack.ll b/llvm/test/CodeGen/AArch64/wineh-align-stack.ll --- a/llvm/test/CodeGen/AArch64/wineh-align-stack.ll +++ b/llvm/test/CodeGen/AArch64/wineh-align-stack.ll @@ -17,11 +17,6 @@ ; 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. diff --git a/llvm/test/CodeGen/AArch64/wineh-frame6.mir b/llvm/test/CodeGen/AArch64/wineh-frame6.mir --- a/llvm/test/CodeGen/AArch64/wineh-frame6.mir +++ b/llvm/test/CodeGen/AArch64/wineh-frame6.mir @@ -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 diff --git a/llvm/test/CodeGen/AArch64/wineh-try-catch.ll b/llvm/test/CodeGen/AArch64/wineh-try-catch.ll --- a/llvm/test/CodeGen/AArch64/wineh-try-catch.ll +++ b/llvm/test/CodeGen/AArch64/wineh-try-catch.ll @@ -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]