OSDN Git Service

[X86][SSE] Add support for decoding PACKSS/PACKUS shuffles masks with UNDEF
authorSimon Pilgrim <llvm-dev@redking.me.uk>
Tue, 3 Oct 2017 12:41:39 +0000 (12:41 +0000)
committerSimon Pilgrim <llvm-dev@redking.me.uk>
Tue, 3 Oct 2017 12:41:39 +0000 (12:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@314792 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/avx2-vbroadcast.ll

index 5f82c85..b02cb8b 100644 (file)
@@ -5967,13 +5967,13 @@ static bool getFauxShuffleMask(SDValue N, SmallVectorImpl<int> &Mask,
     // If we know input saturation won't happen we can treat this
     // as a truncation shuffle.
     if (Opcode == X86ISD::PACKSS) {
-      if (DAG.ComputeNumSignBits(N0) <= NumBitsPerElt ||
-          DAG.ComputeNumSignBits(N1) <= NumBitsPerElt)
+      if ((!N0.isUndef() && DAG.ComputeNumSignBits(N0) <= NumBitsPerElt) ||
+          (!N1.isUndef() && DAG.ComputeNumSignBits(N1) <= NumBitsPerElt))
         return false;
     } else {
       APInt ZeroMask = APInt::getHighBitsSet(2 * NumBitsPerElt, NumBitsPerElt);
-      if (!DAG.MaskedValueIsZero(N0, ZeroMask) ||
-          !DAG.MaskedValueIsZero(N1, ZeroMask))
+      if ((!N0.isUndef() && !DAG.MaskedValueIsZero(N0, ZeroMask)) ||
+          (!N1.isUndef() && !DAG.MaskedValueIsZero(N1, ZeroMask)))
         return false;
     }
 
@@ -6042,6 +6042,14 @@ static void resolveTargetShuffleInputsAndMask(SmallVectorImpl<SDValue> &Inputs,
   for (int i = 0, e = Inputs.size(); i < e; ++i) {
     int lo = UsedInputs.size() * MaskWidth;
     int hi = lo + MaskWidth;
+
+    // Strip UNDEF input usage.
+    if (Inputs[i].isUndef())
+      for (int &M : Mask)
+        if ((lo <= M) && (M < hi))
+          M = SM_SentinelUndef;
+
+    // Check for unused inputs.
     if (any_of(Mask, [lo, hi](int i) { return (lo <= i) && (i < hi); })) {
       UsedInputs.push_back(Inputs[i]);
       continue;
index 8daafb0..0b3a919 100644 (file)
@@ -267,16 +267,14 @@ define <16 x i16> @broadcast_mem_v4i16_v16i16(<4 x i16>* %ptr) {
 ; X32-AVX2-LABEL: broadcast_mem_v4i16_v16i16:
 ; X32-AVX2:       ## BB#0:
 ; X32-AVX2-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X32-AVX2-NEXT:    vpmovzxwd {{.*#+}} xmm0 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero
-; X32-AVX2-NEXT:    vpackusdw %xmm0, %xmm0, %xmm0
-; X32-AVX2-NEXT:    vpbroadcastq %xmm0, %ymm0
+; X32-AVX2-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
+; X32-AVX2-NEXT:    vbroadcastsd %xmm0, %ymm0
 ; X32-AVX2-NEXT:    retl
 ;
 ; X64-AVX2-LABEL: broadcast_mem_v4i16_v16i16:
 ; X64-AVX2:       ## BB#0:
-; X64-AVX2-NEXT:    vpmovzxwd {{.*#+}} xmm0 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero
-; X64-AVX2-NEXT:    vpackusdw %xmm0, %xmm0, %xmm0
-; X64-AVX2-NEXT:    vpbroadcastq %xmm0, %ymm0
+; X64-AVX2-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
+; X64-AVX2-NEXT:    vbroadcastsd %xmm0, %ymm0
 ; X64-AVX2-NEXT:    retq
 ;
 ; X32-AVX512VL-LABEL: broadcast_mem_v4i16_v16i16: