Introduce the BuildVectorSDNode class that encapsulates the ISD::BUILD_VECTOR
instruction. The class also consolidates the code for detecting constant
splats that's shared across PowerPC and the CellSPU backends (and might be
useful for other backends.) Also introduces SelectionDAG::getBUID_VECTOR() for
generating new BUILD_VECTOR nodes.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@65296 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 4b3935c..883f66a 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2386,8 +2386,7 @@
       // Produce a vector of zeros.
       SDValue El = DAG.getConstant(0, VT.getVectorElementType());
       std::vector<SDValue> Ops(VT.getVectorNumElements(), El);
-      return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), VT,
-                         &Ops[0], Ops.size());
+      return DAG.getBUILD_VECTOR(VT, N->getDebugLoc(), &Ops[0], Ops.size());
     }
   }
 
@@ -3858,8 +3857,7 @@
     }
     MVT VT = MVT::getVectorVT(DstEltVT,
                               BV->getValueType(0).getVectorNumElements());
-    return DAG.getNode(ISD::BUILD_VECTOR, BV->getDebugLoc(), VT,
-                       &Ops[0], Ops.size());
+    return DAG.getBUILD_VECTOR(VT, BV->getDebugLoc(), &Ops[0], Ops.size());
   }
 
   // Otherwise, we're growing or shrinking the elements.  To avoid having to
@@ -3915,8 +3913,7 @@
     }
 
     MVT VT = MVT::getVectorVT(DstEltVT, Ops.size());
-    return DAG.getNode(ISD::BUILD_VECTOR, BV->getDebugLoc(), VT,
-                       &Ops[0], Ops.size());
+    return DAG.getBUILD_VECTOR(VT, BV->getDebugLoc(), &Ops[0], Ops.size());
   }
 
   // Finally, this must be the case where we are shrinking elements: each input
@@ -3950,8 +3947,7 @@
       std::reverse(Ops.end()-NumOutputsPerInput, Ops.end());
   }
 
-  return DAG.getNode(ISD::BUILD_VECTOR, BV->getDebugLoc(), VT,
-                     &Ops[0], Ops.size());
+  return DAG.getBUILD_VECTOR(VT, BV->getDebugLoc(), &Ops[0], Ops.size());
 }
 
 SDValue DAGCombiner::visitFADD(SDNode *N) {
@@ -5084,8 +5080,8 @@
                                 InVec.getNode()->op_end());
     if (Elt < Ops.size())
       Ops[Elt] = InVal;
-    return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(),
-                       InVec.getValueType(), &Ops[0], Ops.size());
+    return DAG.getBUILD_VECTOR(InVec.getValueType(), N->getDebugLoc(),
+                               &Ops[0], Ops.size());
   }
 
   return SDValue();
@@ -5270,13 +5266,13 @@
       // Use an undef build_vector as input for the second operand.
       std::vector<SDValue> UnOps(NumInScalars,
                                  DAG.getUNDEF(EltType));
-      Ops[1] = DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), VT,
-                           &UnOps[0], UnOps.size());
+      Ops[1] = DAG.getBUILD_VECTOR(VT, N->getDebugLoc(),
+                                   &UnOps[0], UnOps.size());
       AddToWorkList(Ops[1].getNode());
     }
 
-    Ops[2] = DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), BuildVecVT,
-                         &BuildVecIndices[0], BuildVecIndices.size());
+    Ops[2] = DAG.getBUILD_VECTOR(BuildVecVT, N->getDebugLoc(),
+                                &BuildVecIndices[0], BuildVecIndices.size());
     return DAG.getNode(ISD::VECTOR_SHUFFLE, N->getDebugLoc(), VT, Ops, 3);
   }
 
@@ -5419,9 +5415,8 @@
       }
     }
 
-    ShufMask = DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(),
-                           ShufMask.getValueType(),
-                           &MappedOps[0], MappedOps.size());
+    ShufMask = DAG.getBUILD_VECTOR(ShufMask.getValueType(), N->getDebugLoc(),
+                                   &MappedOps[0], MappedOps.size());
     AddToWorkList(ShufMask.getNode());
     return DAG.getNode(ISD::VECTOR_SHUFFLE, N->getDebugLoc(),
                        N->getValueType(0), N0,
@@ -5471,10 +5466,10 @@
       Ops.push_back(LHS);
       AddToWorkList(LHS.getNode());
       std::vector<SDValue> ZeroOps(NumElts, DAG.getConstant(0, EVT));
-      Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(),
-                                VT, &ZeroOps[0], ZeroOps.size()));
-      Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(),
-                                MaskVT, &IdxOps[0], IdxOps.size()));
+      Ops.push_back(DAG.getBUILD_VECTOR(VT, N->getDebugLoc(),
+                                        &ZeroOps[0], ZeroOps.size()));
+      Ops.push_back(DAG.getBUILD_VECTOR(MaskVT, N->getDebugLoc(),
+                                        &IdxOps[0], IdxOps.size()));
       SDValue Result = DAG.getNode(ISD::VECTOR_SHUFFLE, N->getDebugLoc(),
                                    VT, &Ops[0], Ops.size());
 
@@ -5543,8 +5538,7 @@
 
     if (Ops.size() == LHS.getNumOperands()) {
       MVT VT = LHS.getValueType();
-      return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), VT,
-                         &Ops[0], Ops.size());
+      return DAG.getBUILD_VECTOR(VT, N->getDebugLoc(), &Ops[0], Ops.size());
     }
   }
 
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 15af7dd..0ab7496 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -353,8 +353,7 @@
           }
         }
       }
-      Mask = DAG.getNode(ISD::BUILD_VECTOR, Mask.getDebugLoc(),
-                         NVT, &Ops[0], Ops.size());
+      Mask = DAG.getBUILD_VECTOR(NVT, Mask.getDebugLoc(), &Ops[0], Ops.size());
     }
     VT = NVT;
     break;
@@ -931,7 +930,7 @@
     }
   }
 
-  return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Scalars[0], Scalars.size());
+  return DAG.getBUILD_VECTOR(VT, dl, &Scalars[0], Scalars.size());
 }
 
 /// GetFPLibCall - Return the right libcall for the given floating point type.
@@ -1290,7 +1289,6 @@
 
         unsigned Line = DSP->getLine();
         unsigned Col = DSP->getColumn();
-
         const Function *F = DAG.getMachineFunction().getFunction();
 
         if (!F->hasFnAttr(Attribute::OptimizeForSize)) {
@@ -1676,8 +1674,8 @@
             else
               ShufOps.push_back(DAG.getConstant(NumElts, ShufMaskEltVT));
           }
-          SDValue ShufMask = DAG.getNode(ISD::BUILD_VECTOR, dl, ShufMaskVT,
-                                           &ShufOps[0], ShufOps.size());
+          SDValue ShufMask = DAG.getBUILD_VECTOR(ShufMaskVT, dl,
+                                                 &ShufOps[0], ShufOps.size());
 
           Result = DAG.getNode(ISD::VECTOR_SHUFFLE, dl, Tmp1.getValueType(),
                                Tmp1, ScVec, ShufMask);
@@ -1756,7 +1754,7 @@
                                       DAG.getConstant(Idx - NumElems, PtrVT)));
         }
       }
-      Result = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], Ops.size());
+      Result = DAG.getBUILD_VECTOR(VT, dl, &Ops[0], Ops.size());
       break;
     }
     case TargetLowering::Promote: {
@@ -1808,8 +1806,8 @@
                                   DAG.getConstant(j, PtrVT)));
       }
     }
-    return LegalizeOp(DAG.getNode(ISD::BUILD_VECTOR, dl, Node->getValueType(0),
-                      &Ops[0], Ops.size()));
+    return LegalizeOp(DAG.getBUILD_VECTOR(Node->getValueType(0), dl,
+                                          &Ops[0], Ops.size()));
   }
 
   case ISD::CALLSEQ_START: {
@@ -3162,7 +3160,7 @@
                                   APInt::getAllOnesValue(EltVT.getSizeInBits()),
                                   EltVT), DAG.getConstant(0, EltVT));
       }
-      Result = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElems);
+      Result = DAG.getBUILD_VECTOR(VT, dl, &Ops[0], NumElems);
       break;
     }
     }
@@ -5557,8 +5555,8 @@
     MVT MaskVT = MVT::getIntVectorWithNumElements(NumElems);
     SDValue Zero = DAG.getConstant(0, MaskVT.getVectorElementType());
     std::vector<SDValue> ZeroVec(NumElems, Zero);
-    SDValue SplatMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MaskVT,
-                                      &ZeroVec[0], ZeroVec.size());
+    SDValue SplatMask = DAG.getBUILD_VECTOR(MaskVT, dl,
+                                            &ZeroVec[0], ZeroVec.size());
 
     // If the target supports VECTOR_SHUFFLE and this shuffle mask, use it.
     if (isShuffleLegal(Node->getValueType(0), SplatMask)) {
@@ -5610,8 +5608,8 @@
       else
         MaskVec[Val2Elts[i]] = DAG.getUNDEF(MaskEltVT);
 
-    SDValue ShuffleMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MaskVT,
-                                        &MaskVec[0], MaskVec.size());
+    SDValue ShuffleMask = DAG.getBUILD_VECTOR(MaskVT, dl,
+                                              &MaskVec[0], MaskVec.size());
 
     // If the target supports SCALAR_TO_VECTOR and this shuffle mask, use it.
     if (TLI.isOperationLegalOrCustom(ISD::SCALAR_TO_VECTOR,
@@ -5957,7 +5955,7 @@
       SDValue Scalar = ScalarizeVectorOp(Source);
       SDValue Result = LegalizeINT_TO_FP(SDValue(), isSigned,
                                          DestEltTy, Scalar, dl);
-      return DAG.getNode(ISD::BUILD_VECTOR, dl, DestTy, Result);
+      return DAG.getBUILD_VECTOR(DestTy, dl, Result);
     }
     SDValue Lo, Hi;
     SplitVectorOp(Source, Lo, Hi);
@@ -7572,7 +7570,7 @@
       Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, InVec,
                                 DAG.getConstant(Idx, PtrVT)));
     }
-    Lo = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT_Lo, &Ops[0], Ops.size());
+    Lo = DAG.getBUILD_VECTOR(NewVT_Lo, dl, &Ops[0], Ops.size());
     Ops.clear();
 
     for (unsigned i = NewNumElts_Lo; i != NumElements; ++i) {
@@ -7590,17 +7588,17 @@
       Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, InVec,
                                 DAG.getConstant(Idx, PtrVT)));
     }
-    Hi = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT_Hi, &Ops[0], Ops.size());
+    Hi = DAG.getBUILD_VECTOR(NewVT_Hi, dl, &Ops[0], Ops.size());
     break;
   }
   case ISD::BUILD_VECTOR: {
     SmallVector<SDValue, 8> LoOps(Node->op_begin(),
                                     Node->op_begin()+NewNumElts_Lo);
-    Lo = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT_Lo, &LoOps[0], LoOps.size());
+    Lo = DAG.getBUILD_VECTOR(NewVT_Lo, dl, &LoOps[0], LoOps.size());
 
     SmallVector<SDValue, 8> HiOps(Node->op_begin()+NewNumElts_Lo,
                                     Node->op_end());
-    Hi = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT_Hi, &HiOps[0], HiOps.size());
+    Hi = DAG.getBUILD_VECTOR(NewVT_Hi, dl, &HiOps[0], HiOps.size());
     break;
   }
   case ISD::CONCAT_VECTORS: {
@@ -8066,8 +8064,7 @@
     for (unsigned i = NumElts; i < NewNumElts; ++i) {
       NewOps.push_back(DAG.getUNDEF(EVT));
     }
-    Result = DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT,
-                         &NewOps[0], NewOps.size());
+    Result = DAG.getBUILD_VECTOR(WidenVT, dl, &NewOps[0], NewOps.size());
     break;
   }
   case ISD::INSERT_VECTOR_ELT: {
@@ -8104,9 +8101,8 @@
       NewOps.push_back(DAG.getUNDEF(PVT));
     }
 
-    SDValue Tmp3 = DAG.getNode(ISD::BUILD_VECTOR, dl,
-                               MVT::getVectorVT(PVT, NewOps.size()),
-                               &NewOps[0], NewOps.size());
+    SDValue Tmp3 = DAG.getBUILD_VECTOR(MVT::getVectorVT(PVT, NewOps.size()), dl,
+                                       &NewOps[0], NewOps.size());
 
     Result = DAG.getNode(ISD::VECTOR_SHUFFLE, dl, WidenVT, Tmp1, Tmp2, Tmp3);
     break;
@@ -8152,7 +8148,7 @@
         Ops[i] = UndefVal;
 
       MVT NewInVT = MVT::getVectorVT(InVT, NewNumElts);
-      Result = DAG.getNode(ISD::BUILD_VECTOR, dl, NewInVT, &Ops[0], NewNumElts);
+      Result = DAG.getBUILD_VECTOR(NewInVT, dl, &Ops[0], NewNumElts);
       Result = DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, Result);
     }
     break;
diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 661391b..b89d07f 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -810,9 +810,8 @@
     NewElts.push_back(JoinIntegers(Lo, Hi));
   }
 
-  SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl,
-                                 MVT::getVectorVT(NewVT, NewElts.size()),
-                                 &NewElts[0], NewElts.size());
+  SDValue NewVec = DAG.getBUILD_VECTOR(MVT::getVectorVT(NewVT, NewElts.size()),
+                                       dl, &NewElts[0], NewElts.size());
 
   // Convert the new vector to the old vector type.
   return DAG.getNode(ISD::BIT_CONVERT, dl, VecVT, NewVec);
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
index 65c0020..7a9210b 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
@@ -246,7 +246,7 @@
       if (TLI.isBigEndian())
         std::swap(Parts[0], Parts[1]);
 
-      SDValue Vec = DAG.getNode(ISD::BUILD_VECTOR, dl, NVT, Parts, 2);
+      SDValue Vec = DAG.getBUILD_VECTOR(NVT, dl, Parts, 2);
       return DAG.getNode(ISD::BIT_CONVERT, dl, N->getValueType(0), Vec);
     }
   }
@@ -277,9 +277,8 @@
     NewElts.push_back(Hi);
   }
 
-  SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl,
-                                 MVT::getVectorVT(NewVT, NewElts.size()),
-                                 &NewElts[0], NewElts.size());
+  SDValue NewVec = DAG.getBUILD_VECTOR(MVT::getVectorVT(NewVT, NewElts.size()),
+                                       dl, &NewElts[0], NewElts.size());
 
   // Convert the new vector to the old vector type.
   return DAG.getNode(ISD::BIT_CONVERT, dl, VecVT, NewVec);
@@ -335,7 +334,7 @@
   SDValue UndefVal = DAG.getUNDEF(Ops[0].getValueType());
   for (unsigned i = 1; i < NumElts; ++i)
     Ops[i] = UndefVal;
-  return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElts);
+  return DAG.getBUILD_VECTOR(VT, dl, &Ops[0], NumElts);
 }
 
 SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) {
diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index e679f01..e58f2d9 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -309,8 +309,8 @@
   SmallVector<SDValue, 8> Ops(N->getNumOperands());
   for (unsigned i = 0, e = N->getNumOperands(); i < e; ++i)
     Ops[i] = GetScalarizedVector(N->getOperand(i));
-  return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), N->getValueType(0),
-                     &Ops[0], Ops.size());
+  return DAG.getBUILD_VECTOR(N->getValueType(0), N->getDebugLoc(),
+                             &Ops[0], Ops.size());
 }
 
 /// ScalarizeVecOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to
@@ -501,10 +501,10 @@
   GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
   unsigned LoNumElts = LoVT.getVectorNumElements();
   SmallVector<SDValue, 8> LoOps(N->op_begin(), N->op_begin()+LoNumElts);
-  Lo = DAG.getNode(ISD::BUILD_VECTOR, dl, LoVT, &LoOps[0], LoOps.size());
+  Lo = DAG.getBUILD_VECTOR(LoVT, dl, &LoOps[0], LoOps.size());
 
   SmallVector<SDValue, 8> HiOps(N->op_begin()+LoNumElts, N->op_end());
-  Hi = DAG.getNode(ISD::BUILD_VECTOR, dl, HiVT, &HiOps[0], HiOps.size());
+  Hi = DAG.getBUILD_VECTOR(HiVT, dl, &HiOps[0], HiOps.size());
 }
 
 void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo,
@@ -805,15 +805,14 @@
       }
 
       // Construct the Lo/Hi output using a BUILD_VECTOR.
-      Output = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT, &Ops[0], Ops.size());
+      Output = DAG.getBUILD_VECTOR(NewVT, dl, &Ops[0], Ops.size());
     } else if (InputUsed[0] == -1U) {
       // No input vectors were used!  The result is undefined.
       Output = DAG.getUNDEF(NewVT);
     } else {
       // At least one input vector was used.  Create a new shuffle vector.
-      SDValue NewMask = DAG.getNode(ISD::BUILD_VECTOR, dl,
-                                    MVT::getVectorVT(IdxVT, Ops.size()),
-                                    &Ops[0], Ops.size());
+      SDValue NewMask = DAG.getBUILD_VECTOR(MVT::getVectorVT(IdxVT, Ops.size()),
+                                            dl, &Ops[0], Ops.size());
       SDValue Op0 = Inputs[InputUsed[0]];
       // If only one input was used, use an undefined vector for the other.
       SDValue Op1 = InputUsed[1] == -1U ?
@@ -1080,8 +1079,8 @@
       }
       return DAG.UpdateNodeOperands(SDValue(N,0),
                                     N->getOperand(0), N->getOperand(1),
-                                    DAG.getNode(ISD::BUILD_VECTOR, dl,
-                                                VecVT, &Ops[0], Ops.size()));
+                                    DAG.getBUILD_VECTOR(VecVT, dl,
+                                                        &Ops[0], Ops.size()));
     }
 
     // Continuing is pointless - failure is certain.
@@ -1246,7 +1245,7 @@
   for (; i < WidenNumElts; ++i)
     Ops[i] = UndefVal;
 
-  return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts);
+  return DAG.getBUILD_VECTOR(WidenVT, dl, &Ops[0], WidenNumElts);
 }
 
 SDValue DAGTypeLegalizer::WidenVecRes_Shift(SDNode *N) {
@@ -1344,8 +1343,7 @@
         NewVec = DAG.getNode(ISD::CONCAT_VECTORS, dl,
                              NewInVT, &Ops[0], NewNumElts);
       else
-        NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl,
-                             NewInVT, &Ops[0], NewNumElts);
+        NewVec = DAG.getBUILD_VECTOR(NewInVT, dl, &Ops[0], NewNumElts);
       return DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, NewVec);
     }
   }
@@ -1379,7 +1377,7 @@
   for (unsigned i = NumElts; i < WidenNumElts; ++i)
     NewOps.push_back(DAG.getUNDEF(EltVT));
 
-  return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &NewOps[0], NewOps.size());
+  return DAG.getBUILD_VECTOR(WidenVT, dl, &NewOps[0], NewOps.size());
 }
 
 SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) {
@@ -1425,8 +1423,8 @@
           MaskOps[i] = DAG.getConstant(i, PtrVT);
           MaskOps[i+WidenNumElts/2] = DAG.getConstant(i+WidenNumElts, PtrVT);
         }
-        SDValue Mask = DAG.getNode(ISD::BUILD_VECTOR, dl,
-                                   MVT::getVectorVT(PtrVT, WidenNumElts),
+        SDValue Mask =
+                DAG.getBUILD_VECTOR(MVT::getVectorVT(PtrVT, WidenNumElts), dl,
                                    &MaskOps[0], WidenNumElts);
         return DAG.getNode(ISD::VECTOR_SHUFFLE, dl, WidenVT,
                            GetWidenedVector(N->getOperand(0)),
@@ -1451,7 +1449,7 @@
   SDValue UndefVal = DAG.getUNDEF(EltVT);
   for (; Idx < WidenNumElts; ++Idx)
     Ops[Idx] = UndefVal;
-  return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts);
+  return DAG.getBUILD_VECTOR(WidenVT, dl, &Ops[0], WidenNumElts);
 }
 
 SDValue DAGTypeLegalizer::WidenVecRes_CONVERT_RNDSAT(SDNode *N) {
@@ -1529,7 +1527,7 @@
   for (; i < WidenNumElts; ++i)
     Ops[i] = UndefVal;
 
-  return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts);
+  return DAG.getBUILD_VECTOR(WidenVT, dl, &Ops[0], WidenNumElts);
 }
 
 SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode *N) {
@@ -1582,7 +1580,7 @@
   SDValue UndefVal = DAG.getUNDEF(EltVT);
   for (; i < WidenNumElts; ++i)
     Ops[i] = UndefVal;
-  return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts);
+  return DAG.getBUILD_VECTOR(WidenVT, dl, &Ops[0], WidenNumElts);
 }
 
 SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) {
@@ -1639,7 +1637,7 @@
     for (; i != WidenNumElts; ++i)
       Ops[i] = UndefVal;
 
-    Result =  DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], Ops.size());
+    Result =  DAG.getBUILD_VECTOR(WidenVT, dl, &Ops[0], Ops.size());
   } else {
     assert(LdVT.getVectorElementType() == WidenVT.getVectorElementType());
     unsigned int LdWidth = LdVT.getSizeInBits();
@@ -1735,9 +1733,8 @@
   }
   for (unsigned i = NumElts; i < WidenNumElts; ++i)
     MaskOps[i] = DAG.getUNDEF(IdxVT);
-  SDValue NewMask = DAG.getNode(ISD::BUILD_VECTOR, dl,
-                                MVT::getVectorVT(IdxVT, WidenNumElts),
-                                &MaskOps[0], WidenNumElts);
+  SDValue NewMask = DAG.getBUILD_VECTOR(MVT::getVectorVT(IdxVT, WidenNumElts),
+                                        dl, &MaskOps[0], WidenNumElts);
 
   return DAG.getNode(ISD::VECTOR_SHUFFLE, dl, WidenVT, InOp1, InOp2, NewMask);
 }
@@ -1830,7 +1827,7 @@
                          DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, InEltVT, InOp,
                                      DAG.getIntPtrConstant(i)));
 
-  return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElts);
+  return DAG.getBUILD_VECTOR(VT, dl, &Ops[0], NumElts);
 }
 
 SDValue DAGTypeLegalizer::WidenVecOp_BIT_CONVERT(SDNode *N) {
@@ -1889,7 +1886,7 @@
       Ops[Idx++] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp,
                                DAG.getIntPtrConstant(j));
   }
-  return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElts);
+  return DAG.getBUILD_VECTOR(VT, dl, &Ops[0], NumElts);
 }
 
 SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
@@ -2179,5 +2176,5 @@
   SDValue UndefVal = DAG.getUNDEF(EltVT);
   for ( ; Idx < WidenNumElts; ++Idx)
     Ops[Idx] = UndefVal;
-  return DAG.getNode(ISD::BUILD_VECTOR, dl, NVT, &Ops[0], WidenNumElts);
+  return DAG.getBUILD_VECTOR(NVT, dl, &Ops[0], WidenNumElts);
 }
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 3f16344..66356f5 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -847,7 +847,7 @@
     SDValue NegOneElt =
       getConstant(APInt::getAllOnesValue(EltVT.getSizeInBits()), EltVT);
     std::vector<SDValue> NegOnes(VT.getVectorNumElements(), NegOneElt);
-    NegOne = getNode(ISD::BUILD_VECTOR, DL, VT, &NegOnes[0], NegOnes.size());
+    NegOne = getBUILD_VECTOR(VT, DL, &NegOnes[0], NegOnes.size());
   } else {
     NegOne = getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT);
   }
@@ -893,8 +893,8 @@
   if (VT.isVector()) {
     SmallVector<SDValue, 8> Ops;
     Ops.assign(VT.getVectorNumElements(), Result);
-    Result = getNode(ISD::BUILD_VECTOR, DebugLoc::getUnknownLoc(),
-                     VT, &Ops[0], Ops.size());
+    Result = getBUILD_VECTOR(VT, DebugLoc::getUnknownLoc(),
+			     &Ops[0], Ops.size());
   }
   return Result;
 }
@@ -937,9 +937,8 @@
   if (VT.isVector()) {
     SmallVector<SDValue, 8> Ops;
     Ops.assign(VT.getVectorNumElements(), Result);
-    // FIXME DebugLoc info might be appropriate here
-    Result = getNode(ISD::BUILD_VECTOR, DebugLoc::getUnknownLoc(),
-                     VT, &Ops[0], Ops.size());
+    Result = getBUILD_VECTOR(VT, DebugLoc::getUnknownLoc(),
+			     &Ops[0], Ops.size());
   }
   return Result;
 }
@@ -1078,6 +1077,39 @@
   return SDValue(N, 0);
 }
 
+SDValue SelectionDAG::getBUILD_VECTOR(MVT vecVT, DebugLoc dl, SDValue E1) {
+  return getBUILD_VECTOR(vecVT, dl, &E1, 1);
+}
+
+SDValue SelectionDAG::getBUILD_VECTOR(MVT vecVT, DebugLoc dl, SDValue E1,
+                                      SDValue E2) {
+  SDValue Ops[2] = { E1, E2 };
+  return getBUILD_VECTOR(vecVT, dl, &Ops[0], 2);
+}
+
+SDValue SelectionDAG::getBUILD_VECTOR(MVT vecVT, DebugLoc dl, SDValue E1,
+                                      SDValue E2, SDValue E3, SDValue E4) {
+  SDValue Ops[4] = { E1, E2, E3, E4 };
+  return getBUILD_VECTOR(vecVT, dl, &Ops[0], 4);
+}
+
+SDValue SelectionDAG::getBUILD_VECTOR(MVT vecVT, DebugLoc dl,
+                                      const SDValue *Elts, unsigned NumElts) {
+  FoldingSetNodeID ID;
+  void *IP = 0;
+  SDNode *N = 0;
+
+  AddNodeIDNode(ID, ISD::BUILD_VECTOR, getVTList(vecVT), Elts, NumElts);
+  if ((N = CSEMap.FindNodeOrInsertPos(ID, IP)) == 0) {
+    N = NodeAllocator.Allocate<BuildVectorSDNode>();
+    new (N) BuildVectorSDNode(vecVT, dl, Elts, NumElts);
+    CSEMap.InsertNode(N, IP);
+    AllNodes.push_back(N);
+  }
+
+  return SDValue(N, 0);
+}
+
 SDValue SelectionDAG::getArgFlags(ISD::ArgFlagsTy Flags) {
   FoldingSetNodeID ID;
   AddNodeIDNode(ID, ISD::ARG_FLAGS, getVTList(MVT::Other), 0, 0);
@@ -2409,7 +2441,7 @@
         N2.getOpcode() == ISD::BUILD_VECTOR) {
       SmallVector<SDValue, 16> Elts(N1.getNode()->op_begin(), N1.getNode()->op_end());
       Elts.insert(Elts.end(), N2.getNode()->op_begin(), N2.getNode()->op_end());
-      return getNode(ISD::BUILD_VECTOR, DL, VT, &Elts[0], Elts.size());
+      return getBUILD_VECTOR(VT, DL, &Elts[0], Elts.size());
     }
     break;
   case ISD::AND:
@@ -2763,7 +2795,7 @@
       SmallVector<SDValue, 16> Elts(N1.getNode()->op_begin(), N1.getNode()->op_end());
       Elts.insert(Elts.end(), N2.getNode()->op_begin(), N2.getNode()->op_end());
       Elts.insert(Elts.end(), N3.getNode()->op_begin(), N3.getNode()->op_end());
-      return getNode(ISD::BUILD_VECTOR, DL, VT, &Elts[0], Elts.size());
+      return getBUILD_VECTOR(VT, DL, &Elts[0], Elts.size());
     }
     break;
   case ISD::SETCC: {
@@ -4822,6 +4854,111 @@
   assert(isVolatile() == vol && "Volatile representation error!");
 }
 
+BuildVectorSDNode::BuildVectorSDNode(MVT vecVT, DebugLoc dl,
+				     const SDValue *Elts, unsigned NumElts)
+  : SDNode(ISD::BUILD_VECTOR, dl, getSDVTList(vecVT), Elts, NumElts),
+    computedSplat(false), isSplatVector(false), hasUndefSplatBitsFlag(false),
+    SplatBits(0LL), SplatUndef(0LL), SplatSize(0)
+{ }
+
+bool BuildVectorSDNode::isConstantSplat(int MinSplatBits)  {
+  unsigned int nOps = getNumOperands();
+  assert(nOps > 0 && "isConstantSplat has 0-size build vector");
+
+  // Return early if we already know the answer:
+  if (computedSplat)
+    return isSplatVector;
+
+  // The vector's used (non-undef) bits
+  uint64_t VectorBits[2] = { 0, 0 };
+  // The vector's undefined bits
+  uint64_t UndefBits[2] = { 0, 0 };
+
+  // Assume that this isn't a constant splat.
+  isSplatVector = false;
+
+  // Gather the constant and undefined bits
+  unsigned EltBitSize = getOperand(0).getValueType().getSizeInBits();
+  for (unsigned i = 0; i < nOps; ++i) {
+    SDValue OpVal = getOperand(i);
+    unsigned PartNo = i >= nOps/2;     // In the upper 128 bits?
+    unsigned SlotNo = nOps/2 - (i & (nOps/2-1))-1;// Which subpiece of the uint64_t.
+    uint64_t EltBits = 0;
+
+    if (OpVal.getOpcode() == ISD::UNDEF) {
+      uint64_t EltUndefBits = ~0U >> (32-EltBitSize);
+      UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
+      continue;
+    } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
+      EltBits = CN->getZExtValue();
+      if (EltBitSize <= 32)
+	EltBits &= (~0U >> (32-EltBitSize));
+    } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
+      const APFloat &apf = CN->getValueAPF();
+      if (OpVal.getValueType() == MVT::f32)
+	EltBits = FloatToBits(apf.convertToFloat());
+      else
+	EltBits = DoubleToBits(apf.convertToDouble());
+    } else {
+      // Nonconstant element -> not a splat.
+      computedSplat = true;
+      return isSplatVector;
+    }
+
+    VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
+  }
+
+  if ((VectorBits[0] & ~UndefBits[1]) != (VectorBits[1] & ~UndefBits[0])) {
+    // Can't be a splat if two pieces don't match.
+    computedSplat = true;
+    return isSplatVector;
+  }
+
+  // Don't let undefs prevent splats from matching. See if the top 64-bits
+  // are the same as the lower 64-bits, ignoring undefs.
+  uint64_t Bits64  = VectorBits[0] | VectorBits[1];
+  uint64_t Undef64 = UndefBits[0] & UndefBits[1];
+  uint32_t Bits32  = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
+  uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
+  uint16_t Bits16  = uint16_t(Bits32)  | uint16_t(Bits32 >> 16);
+  uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
+
+  bool splat64 =
+    (VectorBits[0] & ~UndefBits[1]) == (VectorBits[1] & ~UndefBits[0]);
+  bool splat32 = (Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64);
+  bool splat16 = (Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Undef32);
+  bool splat8 =
+    (Bits16 & (uint16_t(~Undef16) >> 8)) == ((Bits16 >> 8) & ~Undef16);
+
+  hasUndefSplatBitsFlag = ((UndefBits[0] | UndefBits[1]) != 0);
+
+  if (splat64 && (MinSplatBits >= 64 || !splat32)) {
+    SplatBits = VectorBits[0];
+    SplatUndef = UndefBits[0];
+    SplatSize = 8;
+    isSplatVector = true;
+  } else if (splat32 && (MinSplatBits >= 32 || !splat16)) {
+    SplatBits = Bits32;
+    SplatUndef = Undef32;
+    SplatSize = 4;
+    isSplatVector = true;
+  } else if (splat16 && (MinSplatBits >= 16 || !splat8)) {
+    SplatBits = Bits16;
+    SplatUndef = Undef16;
+    SplatSize = 2;
+    isSplatVector = true;
+  } else if (splat8) {
+    SplatBits = uint8_t(Bits16) | uint8_t(Bits16 >> 8);
+    SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
+    SplatSize = 1;
+    isSplatVector = true;
+  }
+
+  computedSplat = true;
+  return isSplatVector;
+}
+
+
 /// getMemOperand - Return a MachineMemOperand object describing the memory
 /// reference performed by this memory reference.
 MachineMemOperand MemSDNode::getMemOperand() const {
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
index 205b7b9..4c73729 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
@@ -533,7 +533,7 @@
     assert(ValueVT.getVectorElementType() == PartVT &&
            ValueVT.getVectorNumElements() == 1 &&
            "Only trivial scalar-to-vector conversions should get here!");
-    return DAG.getNode(ISD::BUILD_VECTOR, dl, ValueVT, Val);
+    return DAG.getBUILD_VECTOR(ValueVT, dl, Val);
   }
 
   if (PartVT.isInteger() &&
@@ -935,8 +935,8 @@
     }
 
     // Create a BUILD_VECTOR node.
-    return NodeMap[V] = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(),
-                                    VT, &Ops[0], Ops.size());
+    return NodeMap[V] = DAG.getBUILD_VECTOR(VT, getCurDebugLoc(),
+                                            &Ops[0], Ops.size());
   }
 
   // If this is a static alloca, generate it as the frameindex instead of
@@ -2470,9 +2470,8 @@
                                               MaskEltVT));
       }
     }
-    Mask = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(),
-                       Mask.getValueType(),
-                       &MappedOps[0], MappedOps.size());
+    Mask = DAG.getBUILD_VECTOR(Mask.getValueType(), getCurDebugLoc(),
+                               &MappedOps[0], MappedOps.size());
 
     setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, getCurDebugLoc(),
                              VT, Src1, Src2, Mask));
@@ -2570,9 +2569,8 @@
           }
         }
       }
-      Mask = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(),
-                         Mask.getValueType(),
-                         &MappedOps[0], MappedOps.size());
+      Mask = DAG.getBUILD_VECTOR(Mask.getValueType(), getCurDebugLoc(),
+                                 &MappedOps[0], MappedOps.size());
       setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, getCurDebugLoc(),
                                VT, Src1, Src2, Mask));
       return;
@@ -2601,8 +2599,7 @@
                                   DAG.getConstant(Idx - SrcNumElts, PtrVT)));
     }
   }
-  setValue(&I, DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(),
-                           VT, &Ops[0], Ops.size()));
+  setValue(&I, DAG.getBUILD_VECTOR(VT, getCurDebugLoc(), &Ops[0], Ops.size()));
 }
 
 void SelectionDAGLowering::visitInsertValue(InsertValueInst &I) {