@@ -1948,23 +1948,32 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
1948
1948
bool EmitCFI = MF.getInfo <AArch64FunctionInfo>()->needsAsyncDwarfUnwindInfo ();
1949
1949
bool HasWinCFI = false ;
1950
1950
bool IsFunclet = false ;
1951
- auto WinCFI = make_scope_exit ([&]() { assert (HasWinCFI == MF.hasWinCFI ()); });
1952
1951
1953
1952
if (MBB.end () != MBBI) {
1954
1953
DL = MBBI->getDebugLoc ();
1955
1954
IsFunclet = isFuncletReturnInstr (*MBBI);
1956
1955
}
1957
1956
1957
+ MachineBasicBlock::iterator EpilogStartI = MBB.end ();
1958
+
1958
1959
auto FinishingTouches = make_scope_exit ([&]() {
1959
1960
InsertReturnAddressAuth (MF, MBB, NeedsWinCFI, &HasWinCFI);
1960
1961
if (needsShadowCallStackPrologueEpilogue (MF))
1961
1962
emitShadowCallStackEpilogue (*TII, MF, MBB, MBB.getFirstTerminator (), DL);
1962
1963
if (EmitCFI)
1963
1964
emitCalleeSavedGPRRestores (MBB, MBB.getFirstTerminator ());
1964
- if (HasWinCFI)
1965
+ if (HasWinCFI) {
1965
1966
BuildMI (MBB, MBB.getFirstTerminator (), DL,
1966
1967
TII->get (AArch64::SEH_EpilogEnd))
1967
1968
.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
+ }
1968
1977
});
1969
1978
1970
1979
int64_t NumBytes = IsFunclet ? getWinEHFuncletFrameSize (MF)
@@ -2029,7 +2038,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
2029
2038
// Adjust local stack
2030
2039
emitFrameOffset (MBB, LastPopI, DL, AArch64::SP, AArch64::SP,
2031
2040
StackOffset::getFixed (AFI->getLocalStackSize ()), TII,
2032
- MachineInstr::FrameDestroy, false , NeedsWinCFI);
2041
+ MachineInstr::FrameDestroy, false , NeedsWinCFI, &HasWinCFI );
2033
2042
2034
2043
// SP has been already adjusted while restoring callee save regs.
2035
2044
// We've bailed-out the case with adjusting SP for arguments.
@@ -2081,16 +2090,17 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
2081
2090
NeedsWinCFI, &HasWinCFI);
2082
2091
}
2083
2092
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.
2092
2100
BuildMI (MBB, LastPopI, DL, TII->get (AArch64::SEH_EpilogStart))
2093
2101
.setMIFlag (MachineInstr::FrameDestroy);
2102
+ EpilogStartI = LastPopI;
2103
+ --EpilogStartI;
2094
2104
}
2095
2105
2096
2106
if (hasFP (MF) && AFI->hasSwiftAsyncContext ()) {
@@ -2244,11 +2254,11 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
2244
2254
emitFrameOffset (
2245
2255
MBB, LastPopI, DL, AArch64::SP, AArch64::FP,
2246
2256
StackOffset::getFixed (-AFI->getCalleeSaveBaseToFrameRecordOffset ()),
2247
- TII, MachineInstr::FrameDestroy, false , NeedsWinCFI);
2257
+ TII, MachineInstr::FrameDestroy, false , NeedsWinCFI, &HasWinCFI );
2248
2258
} else if (NumBytes)
2249
2259
emitFrameOffset (MBB, LastPopI, DL, AArch64::SP, AArch64::SP,
2250
2260
StackOffset::getFixed (NumBytes), TII,
2251
- MachineInstr::FrameDestroy, false , NeedsWinCFI);
2261
+ MachineInstr::FrameDestroy, false , NeedsWinCFI, &HasWinCFI );
2252
2262
2253
2263
// When we are about to restore the CSRs, the CFA register is SP again.
2254
2264
if (EmitCFI && hasFP (MF)) {
0 commit comments