Index: lib/Target/X86/X86RegisterInfo.cpp =================================================================== --- lib/Target/X86/X86RegisterInfo.cpp +++ lib/Target/X86/X86RegisterInfo.cpp @@ -220,6 +220,7 @@ 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 @@ 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 @@ 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 Index: test/CodeGen/X86/win64_nonvol.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/win64_nonvol.ll @@ -0,0 +1,31 @@ +; 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: foo: +define x86_64_sysvcc void @foo(i32 %a, i32 %b) { +; CHECK: ret + ret void +} + +; 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 +}