Skip to content

Commit 8cd2244

Browse files
authored
AArch64: correct preserve_most and preserve_all on Windows (#166436)
This fixes register information handling for the `preserve_most` and `preserve_all` calling conventions on Windows ARM64. The root issue was cascading `if` statements whose behavior depended on their order. This patch makes the minimal, tactical change needed for Swift’s two calling conventions, unblocking current work. A broader refactor to remove the ordering dependency is still desired and will follow in a subsequent PR.
1 parent ce091da commit 8cd2244

File tree

3 files changed

+40
-18
lines changed

3 files changed

+40
-18
lines changed

llvm/lib/Target/AArch64/AArch64CallingConvention.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,12 @@ def CSR_Win_AArch64_AAPCS_SwiftError
601601
def CSR_Win_AArch64_AAPCS_SwiftTail
602602
: CalleeSavedRegs<(sub CSR_Win_AArch64_AAPCS, X20, X22)>;
603603

604+
def CSR_Win_AArch64_RT_MostRegs
605+
: CalleeSavedRegs<(add CSR_Win_AArch64_AAPCS, (sequence "X%u", 9, 15))>;
606+
607+
def CSR_Win_AArch64_RT_AllRegs
608+
: CalleeSavedRegs<(add CSR_Win_AArch64_RT_MostRegs, (sequence "Q%u", 8, 31))>;
609+
604610
// The Control Flow Guard check call uses a custom calling convention that also
605611
// preserves X0-X8 and Q0-Q7.
606612
def CSR_Win_AArch64_CFGuard_Check : CalleeSavedRegs<(add CSR_Win_AArch64_AAPCS,

llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,16 @@ AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
9090
if (MF->getSubtarget<AArch64Subtarget>().isTargetDarwin())
9191
return getDarwinCalleeSavedRegs(MF);
9292

93+
if (MF->getFunction().getCallingConv() == CallingConv::PreserveMost)
94+
return MF->getSubtarget<AArch64Subtarget>().isTargetWindows()
95+
? CSR_Win_AArch64_RT_MostRegs_SaveList
96+
: CSR_AArch64_RT_MostRegs_SaveList;
97+
98+
if (MF->getFunction().getCallingConv() == CallingConv::PreserveAll)
99+
return MF->getSubtarget<AArch64Subtarget>().isTargetWindows()
100+
? CSR_Win_AArch64_RT_AllRegs_SaveList
101+
: CSR_AArch64_RT_AllRegs_SaveList;
102+
93103
if (MF->getFunction().getCallingConv() == CallingConv::CFGuard_Check)
94104
return CSR_Win_AArch64_CFGuard_Check_SaveList;
95105
if (MF->getSubtarget<AArch64Subtarget>().isTargetWindows()) {
@@ -138,10 +148,6 @@ AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
138148
return CSR_AArch64_AAPCS_SwiftError_SaveList;
139149
if (MF->getFunction().getCallingConv() == CallingConv::SwiftTail)
140150
return CSR_AArch64_AAPCS_SwiftTail_SaveList;
141-
if (MF->getFunction().getCallingConv() == CallingConv::PreserveMost)
142-
return CSR_AArch64_RT_MostRegs_SaveList;
143-
if (MF->getFunction().getCallingConv() == CallingConv::PreserveAll)
144-
return CSR_AArch64_RT_AllRegs_SaveList;
145151
if (MF->getFunction().getCallingConv() == CallingConv::Win64)
146152
// This is for OSes other than Windows; Windows is a separate case further
147153
// above.

llvm/test/CodeGen/AArch64/preserve_mostcc.ll

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
; RUN: llc < %s -mtriple=arm64-apple-ios-8.0.0 | FileCheck %s
1+
; RUN: llc < %s -mtriple=arm64-apple-ios-8.0.0 | FileCheck -check-prefix CHECK -check-prefix CHECK-DARWIN %s
2+
; RUN: llc < %s -mtriple=aarch64-unknown-windiws-msvc | FileCheck -check-prefix CHECK -check-prefix CHECK-WIN %s
23

34
declare void @standard_cc_func()
45
declare preserve_mostcc void @preserve_mostcc_func()
@@ -8,18 +9,26 @@ declare preserve_mostcc void @preserve_mostcc_func()
89
define preserve_mostcc void @preserve_mostcc1() nounwind {
910
entry:
1011
;CHECK-LABEL: preserve_mostcc1
11-
;CHECK-NOT: stp
12-
;CHECK-NOT: str
13-
;CHECK: str x15
14-
;CHECK-NEXT: stp x14, x13,
15-
;CHECK-NEXT: stp x12, x11,
16-
;CHECK-NEXT: stp x10, x9,
17-
;CHECK: bl _standard_cc_func
12+
;CHECK-DARWIN-NOT: stp
13+
;CHECK-DARWIN-NOT: str
14+
;CHECK-DARWIN: str x15
15+
;CHECK-DARWIN-NEXT: stp x14, x13,
16+
;CHECK-DARWIN-NEXT: stp x12, x11,
17+
;CHECK-DARWIN-NEXT: stp x10, x9,
18+
;CHECK-WIN: stp x15, x14
19+
;CHECK-WIN-NEXT: stp x13, x12,
20+
;CHECK-WIN-NEXT: stp x11, x10,
21+
;CHECK-WIN-NEXT: stp x9, x30
22+
;CHECK: bl {{_?}}standard_cc_func
1823
call void @standard_cc_func()
19-
;CHECK: ldp x10, x9,
20-
;CHECK-NEXT: ldp x12, x11,
21-
;CHECK-NEXT: ldp x14, x13,
22-
;CHECK-NEXT: ldr x15
24+
;CHECK-DARWIN: ldp x10, x9,
25+
;CHECK-DARWIN-NEXT: ldp x12, x11,
26+
;CHECK-DARWIN-NEXT: ldp x14, x13,
27+
;CHECK-DARWIN-NEXT: ldr x15
28+
;CHECK-WIN: ldp x9, x30
29+
;CHECK-WIN-NEXT: ldp x11, x10,
30+
;CHECK-WIN-NEXT: ldp x13, x12,
31+
;CHECK-WIN-NEXT: ldp x15, x14,
2332
ret void
2433
}
2534

@@ -31,9 +40,10 @@ define preserve_mostcc void @preserve_mostcc2() nounwind {
3140
entry:
3241
;CHECK-LABEL: preserve_mostcc2
3342
;CHECK-NOT: x14
34-
;CHECK: stp x29, x30,
43+
;CHECK-DARWIN: stp x29, x30,
44+
;CHECK-WIN: str x30
3545
;CHECK-NOT: x14
36-
;CHECK: bl _preserve_mostcc_func
46+
;CHECK: bl {{_?}}preserve_mostcc_func
3747
call preserve_mostcc void @preserve_mostcc_func()
3848
ret void
3949
}

0 commit comments

Comments
 (0)