From: Craig Topper Date: Mon, 15 Apr 2019 18:39:45 +0000 (+0000) Subject: [X86] Block i32/i64 for 'k' and 'Yk' in getRegForInlineAsmConstraint without avx512bw. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b88655f4c40f478e2fcdee151b704cecabf38744;p=llvm [X86] Block i32/i64 for 'k' and 'Yk' in getRegForInlineAsmConstraint without avx512bw. 32 and 64 bit k-registers require avx512bw. If we don't block this properly, it leads to a crash. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358436 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index c63ea39292f..514df8ccc09 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -43618,20 +43618,18 @@ X86TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, // in the normal allocation? case 'k': if (Subtarget.hasAVX512()) { - // Only supported in AVX512 or later. - switch (VT.SimpleTy) { - default: break; - case MVT::i32: - return std::make_pair(0U, &X86::VK32RegClass); - case MVT::i16: - return std::make_pair(0U, &X86::VK16RegClass); - case MVT::i8: - return std::make_pair(0U, &X86::VK8RegClass); - case MVT::i1: + if (VT == MVT::i1) return std::make_pair(0U, &X86::VK1RegClass); - case MVT::i64: + if (VT == MVT::i8) + return std::make_pair(0U, &X86::VK8RegClass); + if (VT == MVT::i16) + return std::make_pair(0U, &X86::VK16RegClass); + } + if (Subtarget.hasBWI()) { + if (VT == MVT::i32) + return std::make_pair(0U, &X86::VK32RegClass); + if (VT == MVT::i64) return std::make_pair(0U, &X86::VK64RegClass); - } } break; case 'q': // GENERAL_REGS in 64-bit mode, Q_REGS in 32-bit mode. @@ -43753,20 +43751,19 @@ X86TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, return std::make_pair(X86::XMM0, &X86::VR128RegClass); case 'k': // This register class doesn't allocate k0 for masked vector operation. - if (Subtarget.hasAVX512()) { // Only supported in AVX512. - switch (VT.SimpleTy) { - default: break; - case MVT::i32: - return std::make_pair(0U, &X86::VK32WMRegClass); - case MVT::i16: - return std::make_pair(0U, &X86::VK16WMRegClass); - case MVT::i8: - return std::make_pair(0U, &X86::VK8WMRegClass); - case MVT::i1: + if (Subtarget.hasAVX512()) { + if (VT == MVT::i1) return std::make_pair(0U, &X86::VK1WMRegClass); - case MVT::i64: + if (VT == MVT::i8) + return std::make_pair(0U, &X86::VK8WMRegClass); + if (VT == MVT::i16) + return std::make_pair(0U, &X86::VK16WMRegClass); + } + if (Subtarget.hasBWI()) { + if (VT == MVT::i32) + return std::make_pair(0U, &X86::VK32WMRegClass); + if (VT == MVT::i64) return std::make_pair(0U, &X86::VK64WMRegClass); - } } break; } diff --git a/test/CodeGen/X86/asm-reject-vk32-vk64.ll b/test/CodeGen/X86/asm-reject-vk32-vk64.ll new file mode 100644 index 00000000000..12d148a3a74 --- /dev/null +++ b/test/CodeGen/X86/asm-reject-vk32-vk64.ll @@ -0,0 +1,31 @@ +; RUN: not llc -o /dev/null %s -mtriple=x86_64-unknown-unknown -mattr=avx512f 2>&1 | FileCheck %s +; RUN: not llc -o /dev/null %s -mtriple=i386-unknown-unknown -mattr=avx512f 2>&1 | FileCheck %s + +; CHECK: error: couldn't allocate input reg for constraint 'Yk' +define <8 x i64> @mask_Yk_i32(i32 %msk, <8 x i64> %x, <8 x i64> %y) { +entry: + %0 = tail call <8 x i64> asm "vpaddw\09$3, $2, $0 {$1}", "=x,^Yk,x,x,~{dirflag},~{fpsr},~{flags}"(i32 %msk, <8 x i64> %x, <8 x i64> %y) + ret <8 x i64> %0 +} + +; CHECK: error: couldn't allocate input reg for constraint 'Yk' +define <8 x i64> @mask_Yk_i64(i64 %msk, <8 x i64> %x, <8 x i64> %y) { +entry: + %0 = tail call <8 x i64> asm "vpaddb\09$3, $2, $0 {$1}", "=x,^Yk,x,x,~{dirflag},~{fpsr},~{flags}"(i64 %msk, <8 x i64> %x, <8 x i64> %y) + ret <8 x i64> %0 +} + +; CHECK: error: couldn't allocate output register for constraint 'k' +define i32 @k_wise_op_i32(i32 %msk_src1, i32 %msk_src2) { +entry: + %0 = tail call i32 asm "kandd\09$2, $1, $0", "=k,k,k,~{dirflag},~{fpsr},~{flags}"(i32 %msk_src1, i32 %msk_src2) + ret i32 %0 +} + +; CHECK: error: couldn't allocate output register for constraint 'k' +define i64 @k_wise_op_i64(i64 %msk_src1, i64 %msk_src2) { +entry: + %0 = tail call i64 asm "kandq\09$2, $1, $0", "=k,k,k,~{dirflag},~{fpsr},~{flags}"(i64 %msk_src1, i64 %msk_src2) + ret i64 %0 +} +