Index: lib/Target/X86/X86CallingConv.td =================================================================== --- lib/Target/X86/X86CallingConv.td +++ lib/Target/X86/X86CallingConv.td @@ -893,6 +893,11 @@ EDI, ESP)>; def CSR_32_AllRegs_SSE : CalleeSavedRegs<(add CSR_32_AllRegs, (sequence "XMM%u", 0, 7))>; +def CSR_32_AllRegs_AVX : CalleeSavedRegs<(add CSR_32_AllRegs, + (sequence "YMM%u", 0, 7))>; +def CSR_32_AllRegs_AVX512 : CalleeSavedRegs<(add CSR_32_AllRegs, + (sequence "ZMM%u", 0, 7), + (sequence "K%u", 0, 7))>; def CSR_64_AllRegs : CalleeSavedRegs<(add CSR_64_MostRegs, RAX, RSP, (sequence "XMM%u", 16, 31))>; @@ -900,7 +905,8 @@ (sequence "YMM%u", 0, 15)), (sequence "XMM%u", 0, 15))>; def CSR_64_AllRegs_AVX512 : CalleeSavedRegs<(sub (add CSR_64_MostRegs, RAX, RSP, - (sequence "ZMM%u", 0, 31)), + (sequence "ZMM%u", 0, 31), + (sequence "K%u", 0, 7)), (sequence "XMM%u", 0, 15))>; // Standard C + YMM6-15 Index: lib/Target/X86/X86RegisterInfo.cpp =================================================================== --- lib/Target/X86/X86RegisterInfo.cpp +++ lib/Target/X86/X86RegisterInfo.cpp @@ -300,10 +300,13 @@ return CSR_64_AllRegs_AVX_SaveList; return CSR_64_AllRegs_SaveList; } else { + if (HasAVX512) + return CSR_32_AllRegs_AVX512_SaveList; + if (HasAVX) + return CSR_32_AllRegs_AVX_SaveList; if (HasSSE) return CSR_32_AllRegs_SSE_SaveList; - else - return CSR_32_AllRegs_SaveList; + return CSR_32_AllRegs_SaveList; } default: break; @@ -389,16 +392,18 @@ return CSR_64_AllRegs_AVX512_RegMask; if (HasAVX) return CSR_64_AllRegs_AVX_RegMask; - else - return CSR_64_AllRegs_RegMask; + return CSR_64_AllRegs_RegMask; } else { + if (HasAVX512) + return CSR_32_AllRegs_AVX512_RegMask; + if (HasAVX) + return CSR_32_AllRegs_AVX_RegMask; if (HasSSE) return CSR_32_AllRegs_SSE_RegMask; - else - return CSR_32_AllRegs_RegMask; + return CSR_32_AllRegs_RegMask; } - default: - break; + default: + break; } // Unlike getCalleeSavedRegs(), we don't have MMI so we can't check Index: lib/Target/X86/X86RegisterInfo.td =================================================================== --- lib/Target/X86/X86RegisterInfo.td +++ lib/Target/X86/X86RegisterInfo.td @@ -226,14 +226,14 @@ } // Mask Registers, used by AVX-512 instructions. -def K0 : X86Reg<"k0", 0>, DwarfRegNum<[118, -2, -2]>; -def K1 : X86Reg<"k1", 1>, DwarfRegNum<[119, -2, -2]>; -def K2 : X86Reg<"k2", 2>, DwarfRegNum<[120, -2, -2]>; -def K3 : X86Reg<"k3", 3>, DwarfRegNum<[121, -2, -2]>; -def K4 : X86Reg<"k4", 4>, DwarfRegNum<[122, -2, -2]>; -def K5 : X86Reg<"k5", 5>, DwarfRegNum<[123, -2, -2]>; -def K6 : X86Reg<"k6", 6>, DwarfRegNum<[124, -2, -2]>; -def K7 : X86Reg<"k7", 7>, DwarfRegNum<[125, -2, -2]>; +def K0 : X86Reg<"k0", 0>, DwarfRegNum<[118, 93, 93]>; +def K1 : X86Reg<"k1", 1>, DwarfRegNum<[119, 94, 94]>; +def K2 : X86Reg<"k2", 2>, DwarfRegNum<[120, 95, 95]>; +def K3 : X86Reg<"k3", 3>, DwarfRegNum<[121, 96, 96]>; +def K4 : X86Reg<"k4", 4>, DwarfRegNum<[122, 97, 97]>; +def K5 : X86Reg<"k5", 5>, DwarfRegNum<[123, 98, 98]>; +def K6 : X86Reg<"k6", 6>, DwarfRegNum<[124, 99, 99]>; +def K7 : X86Reg<"k7", 7>, DwarfRegNum<[125, 100, 100]>; // Floating point stack registers. These don't map one-to-one to the FP // pseudo registers, but we still mark them as aliasing FP registers. That Index: test/CodeGen/X86/x86-interrupt_cc.ll =================================================================== --- test/CodeGen/X86/x86-interrupt_cc.ll +++ test/CodeGen/X86/x86-interrupt_cc.ll @@ -1,12 +1,26 @@ -; RUN: llc -verify-machineinstrs -mtriple=x86_64-apple-macosx -show-mc-encoding -mattr=+avx512f < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=x86_64-apple-macosx -show-mc-encoding -mattr=+avx512f < %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK64 +; RUN: llc -verify-machineinstrs -mtriple=i386-apple-macosx -show-mc-encoding -mattr=+avx512f < %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK32 - -; Make sure we spill the high numbered YMM registers with the right encoding. +; Make sure we spill the high numbered ZMM registers and K registers with the right encoding. ; CHECK-LABEL: foo -; CHECK: movups %zmm31, {{.+}} -; CHECK: encoding: [0x62,0x61,0x7c,0x48,0x11,0xbc,0x24,0x10,0x08,0x00,0x00] +; CHECK: kmovq %k7, {{.+}} +; CHECK64: encoding: [0xc4,0xe1,0xf8,0x91,0xbc,0x24,0xa0,0x08,0x00,0x00] +; CHECK32: encoding: [0xc4,0xe1,0xf8,0x91,0xbc,0x24,0xa0,0x02,0x00,0x00] +; k6 is used as an anchor for the previous regexp. +; CHECK-NEXT: kmovq %k6 + +; CHECK64: movups %zmm31, {{.+}} +; CHECK64: encoding: [0x62,0x61,0x7c,0x48,0x11,0xbc,0x24,0x10,0x08,0x00,0x00] ; zmm30 is used as an anchor for the previous regexp. -; CHECK-NEXT: movups %zmm30 +; CHECK64-NEXT: movups %zmm30 + +; CHECK32-NOT: zmm31 +; CHECK32-NOT: zmm8 +; CHECK32: movups %zmm7, {{.+}} +; CHECK32: encoding: [0x62,0xf1,0x7c,0x48,0x11,0xbc,0x24,0x10,0x02,0x00,0x00] +; zmm7 is used as an anchor for the previous regexp. +; CHECK32-NEXT: movups %zmm6 + ; CHECK: call ; CHECK: iret