From 6256c0168591c356dcd01858cee1e08f06699ff9 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Mon, 25 Sep 2017 22:00:17 +0000 Subject: [PATCH] X86: remove R12 from CSR on Windows x64 SwiftCC R12 is used for the SwiftError parameter. It is no longer a CSR as it is used for transfer the SwiftError, and the caller must preserve it if they need to. llvm-svn: 314165 --- lib/Target/X86/X86CallingConv.td | 2 ++ lib/Target/X86/X86RegisterInfo.cpp | 39 +++++++++++++++--------------- test/CodeGen/X86/swift-error.ll | 4 +-- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/lib/Target/X86/X86CallingConv.td b/lib/Target/X86/X86CallingConv.td index 64c81391578..2de9a5fbfe9 100644 --- a/lib/Target/X86/X86CallingConv.td +++ b/lib/Target/X86/X86CallingConv.td @@ -1050,6 +1050,8 @@ def CSR_Win64_NoSSE : CalleeSavedRegs<(add RBX, RBP, RDI, RSI, R12, R13, R14, R1 def CSR_Win64 : CalleeSavedRegs<(add CSR_Win64_NoSSE, (sequence "XMM%u", 6, 15))>; +def CSR_Win64_SwiftError : CalleeSavedRegs<(sub CSR_Win64, R12)>; + // The function used by Darwin to obtain the address of a thread-local variable // uses rdi to pass a single parameter and rax for the return value. All other // GPRs are preserved. diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index 343da2573b5..1f49650340e 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -271,12 +271,13 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { assert(MF && "MachineFunction required"); const X86Subtarget &Subtarget = MF->getSubtarget(); + const Function *F = MF->getFunction(); bool HasSSE = Subtarget.hasSSE1(); bool HasAVX = Subtarget.hasAVX(); bool HasAVX512 = Subtarget.hasAVX512(); bool CallsEHReturn = MF->callsEHReturn(); - CallingConv::ID CC = MF->getFunction()->getCallingConv(); + CallingConv::ID CC = F->getCallingConv(); // If attribute NoCallerSavedRegisters exists then we set X86_INTR calling // convention because it has the CSR list. @@ -365,22 +366,20 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { } if (Is64Bit) { - if (IsWin64) { - if (!HasSSE) - return CSR_Win64_NoSSE_SaveList; - return CSR_Win64_SaveList; - } + bool IsSwiftCC = Subtarget.getTargetLowering()->supportSwiftError() && + F->getAttributes().hasAttrSomewhere(Attribute::SwiftError); + if (IsSwiftCC) + return IsWin64 ? CSR_Win64_SwiftError_SaveList + : CSR_64_SwiftError_SaveList; + + if (IsWin64) + return HasSSE ? CSR_Win64_SaveList : CSR_Win64_NoSSE_SaveList; if (CallsEHReturn) return CSR_64EHRet_SaveList; - if (Subtarget.getTargetLowering()->supportSwiftError() && - MF->getFunction()->getAttributes().hasAttrSomewhere( - Attribute::SwiftError)) - return CSR_64_SwiftError_SaveList; return CSR_64_SaveList; } - if (CallsEHReturn) - return CSR_32EHRet_SaveList; - return CSR_32_SaveList; + + return CallsEHReturn ? CSR_32EHRet_SaveList : CSR_32_SaveList; } const MCPhysReg *X86RegisterInfo::getCalleeSavedRegsViaCopy( @@ -479,14 +478,14 @@ X86RegisterInfo::getCallPreservedMask(const MachineFunction &MF, // Unlike getCalleeSavedRegs(), we don't have MMI so we can't check // callsEHReturn(). if (Is64Bit) { - if (IsWin64) - return CSR_Win64_RegMask; - if (Subtarget.getTargetLowering()->supportSwiftError() && - MF.getFunction()->getAttributes().hasAttrSomewhere( - Attribute::SwiftError)) - return CSR_64_SwiftError_RegMask; - return CSR_64_RegMask; + const Function *F = MF.getFunction(); + bool IsSwiftCC = Subtarget.getTargetLowering()->supportSwiftError() && + F->getAttributes().hasAttrSomewhere(Attribute::SwiftError); + if (IsSwiftCC) + return IsWin64 ? CSR_Win64_SwiftError_RegMask : CSR_64_SwiftError_RegMask; + return IsWin64 ? CSR_Win64_RegMask : CSR_64_RegMask; } + return CSR_32_RegMask; } diff --git a/test/CodeGen/X86/swift-error.ll b/test/CodeGen/X86/swift-error.ll index 5fb67d4f3b2..896166a369e 100644 --- a/test/CodeGen/X86/swift-error.ll +++ b/test/CodeGen/X86/swift-error.ll @@ -11,8 +11,8 @@ entry: } ; CHECK-LABEL: g -; CHECK: pushq %r12 +; CHECK-NOT: pushq %r12 ; CHECK: callq f -; CHECK: popq %r12 +; CHECK-NOT: popq %r12 ; CHECK: retq