From d51be017f089137d356219d08f563d7961c664ce Mon Sep 17 00:00:00 2001 From: Charles Davis Date: Fri, 27 Feb 2015 00:57:01 +0000 Subject: [PATCH] Target/X86: Save Win64 non-volatile registers in a Win64 ABI function. Summary: This change causes us to actually save non-volatile registers in a Win64 ABI function that calls a System V ABI function, and vice-versa. Reviewers: rnk Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D7919 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230714 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86RegisterInfo.cpp | 12 +++++++++++- test/CodeGen/X86/win64_nonvol.ll | 28 ++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/X86/win64_nonvol.ll diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index cab7ce801db..f1fd5470c88 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -220,6 +220,7 @@ const MCPhysReg * X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { bool HasAVX = Subtarget.hasAVX(); bool HasAVX512 = Subtarget.hasAVX512(); + bool CallsEHReturn = MF->getMMI().callsEHReturn(); assert(MF && "MachineFunction required"); switch (MF->getFunction()->getCallingConv()) { @@ -253,11 +254,16 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { if (Is64Bit) return CSR_64_MostRegs_SaveList; break; + case CallingConv::X86_64_Win64: + return CSR_Win64_SaveList; + case CallingConv::X86_64_SysV: + if (CallsEHReturn) + return CSR_64EHRet_SaveList; + return CSR_64_SaveList; default: break; } - bool CallsEHReturn = MF->getMMI().callsEHReturn(); if (Is64Bit) { if (IsWin64) return CSR_Win64_SaveList; @@ -308,6 +314,10 @@ X86RegisterInfo::getCallPreservedMask(CallingConv::ID CC) const { break; default: break; + case CallingConv::X86_64_Win64: + return CSR_Win64_RegMask; + case CallingConv::X86_64_SysV: + return CSR_64_RegMask; } // Unlike getCalleeSavedRegs(), we don't have MMI so we can't check diff --git a/test/CodeGen/X86/win64_nonvol.ll b/test/CodeGen/X86/win64_nonvol.ll new file mode 100644 index 00000000000..8e5f6cec1ab --- /dev/null +++ b/test/CodeGen/X86/win64_nonvol.ll @@ -0,0 +1,28 @@ +; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck %s + +; Check that, if a Win64 ABI function calls a SysV ABI function, all the +; Win64 nonvolatile registers get saved. + +; CHECK-LABEL: bar: +define x86_64_win64cc void @bar(i32 %a, i32 %b) { +; CHECK-DAG: pushq %rdi +; CHECK-DAG: pushq %rsi +; CHECK-DAG: movaps %xmm6, +; CHECK-DAG: movaps %xmm7, +; CHECK-DAG: movaps %xmm8, +; CHECK-DAG: movaps %xmm9, +; CHECK-DAG: movaps %xmm10, +; CHECK-DAG: movaps %xmm11, +; CHECK-DAG: movaps %xmm12, +; CHECK-DAG: movaps %xmm13, +; CHECK-DAG: movaps %xmm14, +; CHECK-DAG: movaps %xmm15, +; CHECK: callq foo +; CHECK: ret + call x86_64_sysvcc void @foo(i32 %a, i32 %b) + ret void +} + +declare x86_64_sysvcc void @foo(i32 %a, i32 %b) + -- 2.34.1