- When DAG combiner is folding a bit convert into a BUILD_VECTOR, it should check if it's essentially a SCALAR_TO_VECTOR. Avoid turning (v8i16) <10, u, u, u> to <10, 0, u, u, u, u, u, u>. Instead, simply convert it to a SCALAR_TO_VECTOR of the proper type.
- X86 now normalize SCALAR_TO_VECTOR to (BIT_CONVERT (v4i32 SCALAR_TO_VECTOR)). Get rid of X86ISD::S2VEC.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47290 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 29a31e4..026666c 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -3450,14 +3450,16 @@
         Ops.push_back(DAG.getConstant(NewBits, DstEltVT));
     }
 
-    MVT::ValueType VT = MVT::getVectorType(DstEltVT,
-                                           Ops.size());
+    MVT::ValueType VT = MVT::getVectorType(DstEltVT, Ops.size()); 
     return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size());
   }
   
   // Finally, this must be the case where we are shrinking elements: each input
   // turns into multiple outputs.
+  bool isS2V = ISD::isScalarToVector(BV);
   unsigned NumOutputsPerInput = SrcBitSize/DstBitSize;
+  MVT::ValueType VT = MVT::getVectorType(DstEltVT,
+                                     NumOutputsPerInput * BV->getNumOperands());
   SmallVector<SDOperand, 8> Ops;
   for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
     if (BV->getOperand(i).getOpcode() == ISD::UNDEF) {
@@ -3466,18 +3468,19 @@
       continue;
     }
     uint64_t OpVal = cast<ConstantSDNode>(BV->getOperand(i))->getValue();
-
     for (unsigned j = 0; j != NumOutputsPerInput; ++j) {
       unsigned ThisVal = OpVal & ((1ULL << DstBitSize)-1);
-      OpVal >>= DstBitSize;
       Ops.push_back(DAG.getConstant(ThisVal, DstEltVT));
+      if (isS2V && i == 0 && j == 0 && ThisVal == OpVal)
+        // Simply turn this into a SCALAR_TO_VECTOR of the new type.
+        return DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, Ops[0]);
+      OpVal >>= DstBitSize;
     }
 
     // For big endian targets, swap the order of the pieces of each element.
     if (TLI.isBigEndian())
       std::reverse(Ops.end()-NumOutputsPerInput, Ops.end());
   }
-  MVT::ValueType VT = MVT::getVectorType(DstEltVT, Ops.size());
   return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size());
 }
 
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index c12c98b..f904fa1 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -176,6 +176,27 @@
   return true;
 }
 
+/// isScalarToVector - Return true if the specified node is a
+/// ISD::SCALAR_TO_VECTOR node or a BUILD_VECTOR node where only the low
+/// element is not an undef.
+bool ISD::isScalarToVector(const SDNode *N) {
+  if (N->getOpcode() == ISD::SCALAR_TO_VECTOR)
+    return true;
+
+  if (N->getOpcode() != ISD::BUILD_VECTOR)
+    return false;
+  if (N->getOperand(0).getOpcode() == ISD::UNDEF)
+    return false;
+  unsigned NumElems = N->getNumOperands();
+  for (unsigned i = 1; i < NumElems; ++i) {
+    SDOperand V = N->getOperand(i);
+    if (V.getOpcode() != ISD::UNDEF)
+      return false;
+  }
+  return true;
+}
+
+
 /// isDebugLabel - Return true if the specified node represents a debug
 /// label (i.e. ISD::LABEL or TargetInstrInfo::LABEL node and third operand
 /// is 0).