AVX-512: Added implementation of CONCAT_VECTORS for v8i1 vectors (by Alexey Bader).
authorElena Demikhovsky <elena.demikhovsky@intel.com>
Tue, 17 Dec 2013 08:33:15 +0000 (08:33 +0000)
committerElena Demikhovsky <elena.demikhovsky@intel.com>
Tue, 17 Dec 2013 08:33:15 +0000 (08:33 +0000)
Added implementation of "truncate" from integer type (i64/i32/i16/i8) to i1.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197482 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86ISelLowering.h
lib/Target/X86/X86InstrAVX512.td
lib/Target/X86/X86InstrFragmentsSIMD.td
test/CodeGen/X86/avx512-vec-cmp.ll

index e87e7edab3c83253f17da7d42dd94585fef2b806..3be3bf537557807502c91319dff4b6fef05f39c3 100644 (file)
@@ -1356,7 +1356,7 @@ void X86TargetLowering::resetOperationActions() {
     setOperationAction(ISD::FP_ROUND,           MVT::v8f32, Legal);
     setOperationAction(ISD::FP_EXTEND,          MVT::v8f32, Legal);
 
-    setOperationAction(ISD::TRUNCATE,           MVT::i1, Legal);
+    setOperationAction(ISD::TRUNCATE,           MVT::i1, Custom);
     setOperationAction(ISD::TRUNCATE,           MVT::v16i8, Custom);
     setOperationAction(ISD::TRUNCATE,           MVT::v8i32, Custom);
     setOperationAction(ISD::TRUNCATE,           MVT::v8i1, Custom);
@@ -1374,6 +1374,7 @@ void X86TargetLowering::resetOperationActions() {
     setOperationAction(ISD::CONCAT_VECTORS,     MVT::v16f32,  Custom);
     setOperationAction(ISD::CONCAT_VECTORS,     MVT::v16i32,  Custom);
     setOperationAction(ISD::CONCAT_VECTORS,     MVT::v8i1,    Custom);
+    setOperationAction(ISD::CONCAT_VECTORS,     MVT::v16i1, Legal);
 
     setOperationAction(ISD::SETCC,              MVT::v16i1, Custom);
     setOperationAction(ISD::SETCC,              MVT::v8i1, Custom);
@@ -9066,6 +9067,17 @@ SDValue X86TargetLowering::LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const {
   MVT VT = Op.getSimpleValueType();
   SDValue In = Op.getOperand(0);
   MVT InVT = In.getSimpleValueType();
+
+  if (VT == MVT::i1) {
+    assert((InVT.isInteger() && (InVT.getSizeInBits() <= 64)) &&
+           "Invalid scalar TRUNCATE operation");
+    In = DAG.getNode(ISD::AND, DL, InVT, In, DAG.getConstant(1, InVT));
+    if (InVT.getSizeInBits() == 64)
+      In = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::i32, In);
+    else if (InVT.getSizeInBits() < 32)
+      In = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, In);
+    return DAG.getNode(X86ISD::TRUNC, DL, VT, In);
+  }
   assert(VT.getVectorNumElements() == InVT.getVectorNumElements() &&
          "Invalid TRUNCATE operation");
 
index 0b3495dc1b3b15bf4b8a412c35425f9570b62a5a..03d645c10607520e3512e4e6e7633d0c73f3041e 100644 (file)
@@ -260,6 +260,9 @@ namespace llvm {
       // VTRUNC - Vector integer truncate.
       VTRUNC,
 
+      // TRUNC - Integer truncate
+      TRUNC,
+
       // VTRUNC - Vector integer truncate with mask.
       VTRUNCM,
 
index 2a4053327113c5c4ae6da6053afb89f4491e41ff..7bcbc454c9aeb1a7dbf14003e9accb2820557a2a 100644 (file)
@@ -908,6 +908,9 @@ let Predicates = [HasAVX512] in {
 
   def : Pat<(v8i1 (load addr:$src)),
             (COPY_TO_REGCLASS (KMOVWkm addr:$src), VK8)>;
+
+  def : Pat<(i1 (X86trunc (i32 GR32:$src))),
+            (COPY_TO_REGCLASS (KMOVWkr $src), VK1)>;
 }
 // With AVX-512 only, 8-bit mask is promoted to 16-bit mask.
 let Predicates = [HasAVX512] in {
@@ -1051,6 +1054,10 @@ multiclass avx512_mask_unpck_bw<bits<8> opc, string OpcodeStr> {
 }
 
 defm KUNPCK : avx512_mask_unpck_bw<0x4b, "kunpck">;
+def : Pat<(v16i1 (concat_vectors (v8i1 VK8:$src1), (v8i1 VK8:$src2))),
+          (KUNPCKBWrr (COPY_TO_REGCLASS VK8:$src2, VK16),
+                  (COPY_TO_REGCLASS VK8:$src1, VK16))>;
+
 
 multiclass avx512_mask_unpck_int<string IntName, string InstName> {
   let Predicates = [HasAVX512] in
index b56ce1122dfb97443fc54b337f7b4b1d8edec450..2157de28f1464545c0dbef67293f552df88dc754 100644 (file)
@@ -108,6 +108,9 @@ def X86vsext   : SDNode<"X86ISD::VSEXT",
 def X86vtrunc   : SDNode<"X86ISD::VTRUNC",
                          SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisVec<1>,
                                               SDTCisInt<0>, SDTCisInt<1>]>>;
+def X86trunc    : SDNode<"X86ISD::TRUNC",
+                         SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisInt<1>]>>;
+                                              
 def X86vtruncm   : SDNode<"X86ISD::VTRUNCM",
                          SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>,
                                               SDTCisInt<0>, SDTCisInt<1>,
index 6ca5bcc3b862c6dfc7a862680424e09062da0d92..822809c62eddd95cfb63c606c9ab8afea99f68d5 100644 (file)
@@ -111,3 +111,14 @@ define <8 x i32> @test11_unsigned(<8 x i32> %x, <8 x i32> %y) nounwind {
   %max = select <8 x i1> %mask, <8 x i32> %x, <8 x i32> %y
   ret <8 x i32> %max
 }
+
+; CHECK-LABEL: test12
+; CHECK: vpcmpeqq        %zmm2, %zmm0, [[LO:%k[0-7]]]
+; CHECK: vpcmpeqq        %zmm3, %zmm1, [[HI:%k[0-7]]]
+; CHECK: kunpckbw        [[LO]], [[HI]], {{%k[0-7]}}
+
+define i16 @test12(<16 x i64> %a, <16 x i64> %b) nounwind {
+  %res = icmp eq <16 x i64> %a, %b
+  %res1 = bitcast <16 x i1> %res to i16
+  ret i16 %res1
+}