Skip to content

Commit 91de708

Browse files
authored
Merge pull request #7379 from hjyamauchi/wincfi
[AArch64][WinCFI] Handle cases where no SEH opcodes in the prologue
2 parents 1fd6f48 + 42a9fa6 commit 91de708

File tree

2 files changed

+36
-13
lines changed

2 files changed

+36
-13
lines changed

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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)) {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
; RUN: llc -mtriple=aarch64-windows %s -o - | FileCheck %s
2+
3+
define hidden swifttailcc void @test(ptr noalias nocapture %0, ptr swiftasync %1, ptr %2, ptr noalias nocapture %3, ptr nocapture dereferenceable(8) %4, ptr %5, ptr %6, ptr %Act, ptr %Err, ptr %Res, ptr %Act.DistributedActor, ptr %Err.Error, ptr %Res.Decodable, ptr %Res.Encodable, ptr swiftself %7) #0 {
4+
entry:
5+
ret void
6+
}
7+
8+
; Check that there is no .seh_endprologue but there is seh_startepilogue/seh_endepilogue.
9+
; CHECK-NOT: .seh_endprologue
10+
; CHECK: .seh_startepilogue
11+
; CHECK: add sp, sp, #48
12+
; CHECK: .seh_stackalloc 48
13+
; CHECK: .seh_endepilogue

0 commit comments

Comments
 (0)