Change SelectionDAG type legalization to allow BUILD_VECTOR operands to be
promoted to legal types without changing the type of the vector.  This is
following a suggestion from Duncan
(http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-February/019923.html).
The transformation that used to be done during type legalization is now
postponed to DAG legalization.  This allows the BUILD_VECTORs to be optimized
and potentially handled specially by target-specific code.

It turns out that this is also consistent with an optimization done by the
DAG combiner: a BUILD_VECTOR and INSERT_VECTOR_ELT may be combined by
replacing one of the BUILD_VECTOR operands with the newly inserted element;
but INSERT_VECTOR_ELT allows its scalar operand to be larger than the
element type, with any extra high bits being implicitly truncated.  The
result is a BUILD_VECTOR where one of the operands has a type larger the
the vector element type.

Any code that operates on BUILD_VECTORs may now need to be aware of the
potential type discrepancy between the vector element type and the
BUILD_VECTOR operands.  This patch updates all of the places that I could
find to handle that case.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68996 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 5af12eb..dd4fda1 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -3795,7 +3795,7 @@
 /// destination element value type.
 SDValue DAGCombiner::
 ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT DstEltVT) {
-  MVT SrcEltVT = BV->getOperand(0).getValueType();
+  MVT SrcEltVT = BV->getValueType(0).getVectorElementType();
 
   // If this is already the right type, we're done.
   if (SrcEltVT == DstEltVT) return SDValue(BV, 0);
@@ -3808,8 +3808,17 @@
   if (SrcBitSize == DstBitSize) {
     SmallVector<SDValue, 8> Ops;
     for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
+      SDValue Op = BV->getOperand(i);
+      // If the vector element type is not legal, the BUILD_VECTOR operands
+      // are promoted and implicitly truncated.  Make that explicit here.
+      if (Op.getValueType() != SrcEltVT) {
+        if (Op.getOpcode() == ISD::UNDEF)
+          Op = DAG.getUNDEF(SrcEltVT);
+        else
+          Op = DAG.getNode(ISD::TRUNCATE, BV->getDebugLoc(), SrcEltVT, Op);
+      }
       Ops.push_back(DAG.getNode(ISD::BIT_CONVERT, BV->getDebugLoc(),
-                                DstEltVT, BV->getOperand(i)));
+                                DstEltVT, Op));
       AddToWorkList(Ops.back().getNode());
     }
     MVT VT = MVT::getVectorVT(DstEltVT,
@@ -3860,8 +3869,8 @@
         if (Op.getOpcode() == ISD::UNDEF) continue;
         EltIsUndef = false;
 
-        NewBits |=
-          APInt(cast<ConstantSDNode>(Op)->getAPIntValue()).zext(DstBitSize);
+        NewBits |= (APInt(cast<ConstantSDNode>(Op)->getAPIntValue()).
+                    zextOrTrunc(SrcBitSize).zext(DstBitSize));
       }
 
       if (EltIsUndef)
@@ -3889,7 +3898,8 @@
       continue;
     }
 
-    APInt OpVal = cast<ConstantSDNode>(BV->getOperand(i))->getAPIntValue();
+    APInt OpVal = APInt(cast<ConstantSDNode>(BV->getOperand(i))->
+                        getAPIntValue()).zextOrTrunc(SrcBitSize);
 
     for (unsigned j = 0; j != NumOutputsPerInput; ++j) {
       APInt ThisVal = APInt(OpVal).trunc(DstBitSize);