]> granicus.if.org Git - llvm/commitdiff
[X86][SSE] Add support for extracting target constants from BUILD_VECTOR
authorSimon Pilgrim <llvm-dev@redking.me.uk>
Fri, 10 Feb 2017 14:04:11 +0000 (14:04 +0000)
committerSimon Pilgrim <llvm-dev@redking.me.uk>
Fri, 10 Feb 2017 14:04:11 +0000 (14:04 +0000)
In some cases we call getTargetConstantBitsFromNode for nodes that haven't been lowered from BUILD_VECTOR yet

Note: We're getting very close to being able to move most of the constant extraction code from getTargetShuffleMaskIndices into getTargetConstantBitsFromNode

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

lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/clear_upper_vector_element_bits.ll

index 4fddf3ff1d60bc4936b13e4208f00368edca251d..7200b1cea4592671889ef86ceeffadf5770203bc 100644 (file)
@@ -5212,6 +5212,23 @@ static bool getTargetConstantBitsFromNode(SDValue Op, unsigned EltSizeInBits,
     return false;
   };
 
+  // Extract constant bits from build vector.
+  if (ISD::isBuildVectorOfConstantSDNodes(Op.getNode())) {
+    unsigned SrcEltSizeInBits = VT.getScalarSizeInBits();
+    for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) {
+      const SDValue &Src = Op.getOperand(i);
+      if (Src.isUndef()) {
+        APInt Undefs = APInt::getLowBitsSet(SizeInBits, SrcEltSizeInBits);
+        UndefBits |= Undefs.shl(i * SrcEltSizeInBits);
+        continue;
+      }
+      auto *Cst = cast<ConstantSDNode>(Src);
+      APInt Bits = Cst->getAPIntValue().zextOrTrunc(SrcEltSizeInBits);
+      MaskBits |= Bits.zext(SizeInBits).shl(i * SrcEltSizeInBits);
+    }
+    return SplitBitData();
+  }
+
   // Extract constant bits from constant pool vector.
   if (auto *Cst = getTargetConstantFromNode(Op)) {
     Type *CstTy = Cst->getType();
index 7f91208200cfc0ef16646a39308adaaf8f420daa..6e8c6755f4ee0a7816b0cb0d3e8ed060a42483f0 100644 (file)
@@ -901,23 +901,21 @@ define <16 x i16> @_clearupper16xi16b(<16 x i16>) nounwind {
 ;
 ; AVX1-LABEL: _clearupper16xi16b:
 ; AVX1:       # BB#0:
-; AVX1-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm1
-; AVX1-NEXT:    xorl %eax, %eax
-; AVX1-NEXT:    vpinsrb $15, %eax, %xmm1, %xmm1
-; AVX1-NEXT:    vblendpd {{.*#+}} ymm0 = ymm1[0,1],ymm0[2,3]
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
-; AVX1-NEXT:    vandpd {{.*}}(%rip), %xmm1, %xmm1
+; AVX1-NEXT:    vmovapd {{.*#+}} xmm1 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]
+; AVX1-NEXT:    vandpd %xmm1, %xmm0, %xmm2
+; AVX1-NEXT:    vblendpd {{.*#+}} ymm0 = ymm2[0,1],ymm0[2,3]
+; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
+; AVX1-NEXT:    vandpd %xmm1, %xmm2, %xmm1
 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: _clearupper16xi16b:
 ; AVX2:       # BB#0:
-; AVX2-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm1
-; AVX2-NEXT:    xorl %eax, %eax
-; AVX2-NEXT:    vpinsrb $15, %eax, %xmm1, %xmm1
-; AVX2-NEXT:    vpblendd {{.*#+}} ymm0 = ymm1[0,1,2,3],ymm0[4,5,6,7]
-; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
-; AVX2-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
+; AVX2-NEXT:    vmovdqa {{.*#+}} xmm1 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]
+; AVX2-NEXT:    vpand %xmm1, %xmm0, %xmm2
+; AVX2-NEXT:    vpblendd {{.*#+}} ymm0 = ymm2[0,1,2,3],ymm0[4,5,6,7]
+; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm2
+; AVX2-NEXT:    vpand %xmm1, %xmm2, %xmm1
 ; AVX2-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
 ; AVX2-NEXT:    retq
   %x8 = bitcast <16 x i16> %0 to <32 x i8>