@@ -1948,23 +1948,32 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
19481948 bool EmitCFI = MF.getInfo <AArch64FunctionInfo>()->needsAsyncDwarfUnwindInfo ();
19491949 bool HasWinCFI = false ;
19501950 bool IsFunclet = false ;
1951- auto WinCFI = make_scope_exit ([&]() { assert (HasWinCFI == MF.hasWinCFI ()); });
19521951
19531952 if (MBB.end () != MBBI) {
19541953 DL = MBBI->getDebugLoc ();
19551954 IsFunclet = isFuncletReturnInstr (*MBBI);
19561955 }
19571956
1957+ MachineBasicBlock::iterator EpilogStartI = MBB.end ();
1958+
19581959 auto FinishingTouches = make_scope_exit ([&]() {
19591960 InsertReturnAddressAuth (MF, MBB, NeedsWinCFI, &HasWinCFI);
19601961 if (needsShadowCallStackPrologueEpilogue (MF))
19611962 emitShadowCallStackEpilogue (*TII, MF, MBB, MBB.getFirstTerminator (), DL);
19621963 if (EmitCFI)
19631964 emitCalleeSavedGPRRestores (MBB, MBB.getFirstTerminator ());
1964- if (HasWinCFI)
1965+ if (HasWinCFI) {
19651966 BuildMI (MBB, MBB.getFirstTerminator (), DL,
19661967 TII->get (AArch64::SEH_EpilogEnd))
19671968 .setMIFlag (MachineInstr::FrameDestroy);
1969+ if (!MF.hasWinCFI ())
1970+ MF.setHasWinCFI (true );
1971+ }
1972+ if (NeedsWinCFI) {
1973+ assert (EpilogStartI != MBB.end ());
1974+ if (!HasWinCFI)
1975+ MBB.erase (EpilogStartI);
1976+ }
19681977 });
19691978
19701979 int64_t NumBytes = IsFunclet ? getWinEHFuncletFrameSize (MF)
@@ -2029,7 +2038,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
20292038 // Adjust local stack
20302039 emitFrameOffset (MBB, LastPopI, DL, AArch64::SP, AArch64::SP,
20312040 StackOffset::getFixed (AFI->getLocalStackSize ()), TII,
2032- MachineInstr::FrameDestroy, false , NeedsWinCFI);
2041+ MachineInstr::FrameDestroy, false , NeedsWinCFI, &HasWinCFI );
20332042
20342043 // SP has been already adjusted while restoring callee save regs.
20352044 // We've bailed-out the case with adjusting SP for arguments.
@@ -2081,16 +2090,17 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
20812090 NeedsWinCFI, &HasWinCFI);
20822091 }
20832092
2084- if (MF.hasWinCFI ()) {
2085- // If the prologue didn't contain any SEH opcodes and didn't set the
2086- // MF.hasWinCFI() flag, assume the epilogue won't either, and skip the
2087- // EpilogStart - to avoid generating CFI for functions that don't need it.
2088- // (And as we didn't generate any prologue at all, it would be asymmetrical
2089- // to the epilogue.) By the end of the function, we assert that
2090- // HasWinCFI is equal to MF.hasWinCFI(), to verify this assumption.
2091- HasWinCFI = true ;
2093+ if (NeedsWinCFI) {
2094+ // Note that there are cases where we insert SEH opcodes in the
2095+ // epilogue when we had no SEH opcodes in the prologue. For
2096+ // example, when there is no stack frame but there are stack
2097+ // arguments. Insert the SEH_EpilogStart and remove it later if it
2098+ // we didn't emit any SEH opcodes to avoid generating WinCFI for
2099+ // functions that don't need it.
20922100 BuildMI (MBB, LastPopI, DL, TII->get (AArch64::SEH_EpilogStart))
20932101 .setMIFlag (MachineInstr::FrameDestroy);
2102+ EpilogStartI = LastPopI;
2103+ --EpilogStartI;
20942104 }
20952105
20962106 if (hasFP (MF) && AFI->hasSwiftAsyncContext ()) {
@@ -2244,11 +2254,11 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
22442254 emitFrameOffset (
22452255 MBB, LastPopI, DL, AArch64::SP, AArch64::FP,
22462256 StackOffset::getFixed (-AFI->getCalleeSaveBaseToFrameRecordOffset ()),
2247- TII, MachineInstr::FrameDestroy, false , NeedsWinCFI);
2257+ TII, MachineInstr::FrameDestroy, false , NeedsWinCFI, &HasWinCFI );
22482258 } else if (NumBytes)
22492259 emitFrameOffset (MBB, LastPopI, DL, AArch64::SP, AArch64::SP,
22502260 StackOffset::getFixed (NumBytes), TII,
2251- MachineInstr::FrameDestroy, false , NeedsWinCFI);
2261+ MachineInstr::FrameDestroy, false , NeedsWinCFI, &HasWinCFI );
22522262
22532263 // When we are about to restore the CSRs, the CFA register is SP again.
22542264 if (EmitCFI && hasFP (MF)) {
0 commit comments