[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 c63ea39..514df8c 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -43618,20 +43618,18 @@
       // 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 @@
       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 0000000..12d148a
--- /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
+}
+