Skip to content

Commit 13919d7

Browse files
committed
[AArch64][Windows] Fix the callee-saved registers for swiftcc on Windows/AArch64
Fix a miscompilation crash where swiftself on x20 gets corrupted due to incorrect save/restore at prologue/epilogue.
1 parent 1bb54d5 commit 13919d7

File tree

4 files changed

+41
-6
lines changed

4 files changed

+41
-6
lines changed

llvm/lib/Target/AArch64/AArch64CallingConvention.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,12 @@ def CSR_Win_AArch64_AAPCS : CalleeSavedRegs<(add X19, X20, X21, X22, X23, X24,
416416
D8, D9, D10, D11,
417417
D12, D13, D14, D15)>;
418418

419+
def CSR_Win_AArch64_AAPCS_SwiftError
420+
: CalleeSavedRegs<(sub CSR_Win_AArch64_AAPCS, X21)>;
421+
422+
def CSR_Win_AArch64_AAPCS_SwiftTail
423+
: CalleeSavedRegs<(sub CSR_Win_AArch64_AAPCS, X20, X22)>;
424+
419425
// The Control Flow Guard check call uses a custom calling convention that also
420426
// preserves X0-X8 and Q0-Q7.
421427
def CSR_Win_AArch64_CFGuard_Check : CalleeSavedRegs<(add CSR_Win_AArch64_AAPCS,

llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,16 @@ AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
8585

8686
if (MF->getFunction().getCallingConv() == CallingConv::CFGuard_Check)
8787
return CSR_Win_AArch64_CFGuard_Check_SaveList;
88-
if (MF->getSubtarget<AArch64Subtarget>().isTargetWindows())
88+
if (MF->getSubtarget<AArch64Subtarget>().isTargetWindows()) {
89+
if (MF->getSubtarget<AArch64Subtarget>().getTargetLowering()
90+
->supportSwiftError() &&
91+
MF->getFunction().getAttributes().hasAttrSomewhere(
92+
Attribute::SwiftError))
93+
return CSR_Win_AArch64_AAPCS_SwiftError_SaveList;
94+
if (MF->getFunction().getCallingConv() == CallingConv::SwiftTail)
95+
return CSR_Win_AArch64_AAPCS_SwiftTail_SaveList;
8996
return CSR_Win_AArch64_AAPCS_SaveList;
97+
}
9098
if (MF->getFunction().getCallingConv() == CallingConv::AArch64_VectorCall)
9199
return CSR_AArch64_AAVPCS_SaveList;
92100
if (MF->getFunction().getCallingConv() == CallingConv::AArch64_SVE_VectorCall)

llvm/test/CodeGen/AArch64/swift-async-win.ll

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,11 @@ entryresume.0:
3939
; NOTE: we do not see the canonical windows frame setup due to the `nounwind`
4040
; attribtue on the function.
4141

42-
; CHECK: sub sp, sp, #64
43-
; CHECK: stp x30, x29, [sp, #16]
44-
; CHECK: add x29, sp, #16
45-
; CHECK: stp x22, x21, [sp, #32]
42+
; CHECK: sub sp, sp, #48
43+
; CHECK: stp x30, x29, [sp, #24]
44+
; CHECK: add x29, sp, #24
45+
; CHECK: str x19, [sp, #40]
4646
; CHECK: sub x8, x29, #8
47-
; CHECK: stp x20, x19, [sp, #48]
4847
; CHECK: ldr x9, [x0]
4948
; CHECK: str x9, [x8]
5049

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
; RUN: llc -mtriple aarch64-unknown-windows-msvc %s -o - | FileCheck %s
2+
3+
define internal swifttailcc void @"?future_adapter@@YWXPEAVAsyncContext@swift@@@Z"(ptr noundef swiftasync %_context) #0 {
4+
entry:
5+
%add.ptr = getelementptr inbounds i8, ptr %_context, i64 -32
6+
%asyncEntryPoint = getelementptr inbounds i8, ptr %_context, i64 -24
7+
%0 = load ptr, ptr %asyncEntryPoint, align 8
8+
%closureContext = getelementptr inbounds i8, ptr %_context, i64 -16
9+
%1 = load ptr, ptr %closureContext, align 8
10+
%2 = load ptr, ptr %add.ptr, align 8
11+
musttail call swifttailcc void %0(ptr noundef %2, ptr noundef swiftasync %_context, ptr noundef swiftself %1) #17
12+
ret void
13+
}
14+
15+
; Check that x20 isn't saved/restored at the prologue/epilogue which
16+
; would interfere with the outgoing self parameter on x20 at the tail
17+
; call.
18+
19+
; CHECK-NOT: st{{.*}}x20
20+
; CHECK: ldp x1, x20, [x22, #-24]
21+
; CHECK-NEXT: ldur x0, [x22, #-32]
22+
; CHECK-NEXT: br x1

0 commit comments

Comments
 (0)