diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp @@ -815,7 +815,7 @@ // Tell the call which registers are clobbered. auto TRI = MF.getSubtarget().getRegisterInfo(); - const uint32_t *Mask = TRI->getCallPreservedMask(MF, F.getCallingConv()); + const uint32_t *Mask = TRI->getCallPreservedMask(MF, CalleeCC); if (MF.getSubtarget().hasCustomCallingConv()) TRI->UpdateCustomCallPreservedMask(MF, &Mask); MIB.addRegMask(Mask); @@ -972,7 +972,7 @@ // Tell the call which registers are clobbered. auto TRI = MF.getSubtarget().getRegisterInfo(); - const uint32_t *Mask = TRI->getCallPreservedMask(MF, F.getCallingConv()); + const uint32_t *Mask = TRI->getCallPreservedMask(MF, Info.CallConv); if (MF.getSubtarget().hasCustomCallingConv()) TRI->UpdateCustomCallPreservedMask(MF, &Mask); MIB.addRegMask(Mask); @@ -1003,7 +1003,7 @@ // symmetry with the arugments, the physical register must be an // implicit-define of the call instruction. if (!Info.OrigRet.Ty->isVoidTy()) { - CCAssignFn *RetAssignFn = TLI.CCAssignFnForReturn(F.getCallingConv()); + CCAssignFn *RetAssignFn = TLI.CCAssignFnForReturn(Info.CallConv); CallReturnHandler Handler(MIRBuilder, MRI, MIB, RetAssignFn); if (!handleAssignments(MIRBuilder, InArgs, Handler)) return false; diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -1615,7 +1615,7 @@ ; CHECK-LABEL: name: test_different_call_conv ; CHECK: [[X:%[0-9]+]]:_(s32) = COPY $s0 ; CHECK: $s8 = COPY [[X]] -; CHECK: BL @different_call_conv_target, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $s8, implicit-def $s0 +; CHECK: BL @different_call_conv_target, csr_aarch64_noregs, implicit-def $lr, implicit $sp, implicit $s8, implicit-def $s0 %res = call ghccc float @different_call_conv_target(float %x) ret float %res } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call.ll b/llvm/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call.ll --- a/llvm/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call.ll @@ -158,7 +158,7 @@ ; COMMON-LABEL: name: test_bad_call_conv ; COMMON: bb.1 (%ir-block.0): ; COMMON: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp - ; COMMON: BL @bad_call_conv_fn, csr_aarch64_aapcs, implicit-def $lr, implicit $sp + ; COMMON: BL @bad_call_conv_fn, csr_aarch64_noregs, implicit-def $lr, implicit $sp ; COMMON: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp ; COMMON: RET_ReallyLR tail call ghccc void @bad_call_conv_fn() diff --git a/llvm/test/CodeGen/AArch64/arm64-preserve-most.ll b/llvm/test/CodeGen/AArch64/arm64-preserve-most.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/arm64-preserve-most.ll @@ -0,0 +1,38 @@ +; RUN: llc -O0 --march=aarch64 -verify-machineinstrs --filetype=asm %s -o - 2>&1 | FileCheck %s +; RUN: llc -O1 --march=aarch64 -verify-machineinstrs --filetype=asm %s -o - 2>&1 | FileCheck %s +; RUN: llc -O2 --march=aarch64 -verify-machineinstrs --filetype=asm %s -o - 2>&1 | FileCheck %s +target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" +target triple = "aarch64-unknown-linux-gnu" + +declare void @normal_cc() + +; Caller: preserve_mostcc; callee: normalcc. All normally callee saved registers +; (x9 ~ x15) need to be spilled. Since most of them will be spilled in pairs +; in reverse order, we only check the odd number ones since the same line of +; assembly cannot be matched twice. +; CHECK-LABEL: preserve_most +; CHECK-DAG: {{st[rp]}} {{(x[0-9]+, )?x9(, x[0-9]+)?}}, [sp, #{{[-0-9]+}}] +; CHECK-DAG: {{st[rp]}} {{(x[0-9]+, )?x11(, x[0-9]+)?}}, [sp, #{{[-0-9]+}}] +; CHECK-DAG: {{st[rp]}} {{(x[0-9]+, )?x13(, x[0-9]+)?}}, [sp, #{{[-0-9]+}}] +; CHECK-DAG: {{st[rp]}} {{(x[0-9]+, )?x15(, x[0-9]+)?}}, [sp, #{{[-0-9]+}}] +define preserve_mostcc void @preserve_most() { + call void @normal_cc() + ret void +} + +; Caller: normalcc; callee: preserve_mostcc. x9 does not need to be spilled. +; The same holds for x10 through x15, but we only check x9. +; CHECK-LABEL: normal_cc_caller +; CHECK-NOT: stp {{x[0-9]+}}, x9, [sp, #{{[-0-9]+}}] +; CHECK-NOT: stp x9, {{x[0-9]+}}, [sp, #{{[-0-9]+}}] +; CHECK-NOT: str x9, [sp, {{#[-0-9]+}}]! +define dso_local void @normal_cc_caller() { +entry: + %v = alloca i32, align 4 + call void asm sideeffect "mov x9, $0", "N,~{x9}"(i32 48879) #2 + call preserve_mostcc void @preserve_most() + %0 = load i32, i32* %v, align 4 + %1 = call i32 asm sideeffect "mov ${0:w}, w9", "=r,r"(i32 %0) #2 + store i32 %1, i32* %v, align 4 + ret void +}