Vector codegen improvements


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62458 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index d6cc16c..e6eb9c0b 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -409,10 +409,26 @@
   }
   
   // A scalar can be splatted to an extended vector of the same element type
-  if (DstType->isExtVectorType() && !isa<VectorType>(SrcType) &&
-      cast<llvm::VectorType>(DstTy)->getElementType() == Src->getType())
-    return CGF.EmitVector(&Src, DstType->getAsVectorType()->getNumElements(), 
-                          true);
+  if (DstType->isExtVectorType() && !isa<VectorType>(SrcType)) {
+    // Cast the scalar to element type
+    QualType EltTy = DstType->getAsExtVectorType()->getElementType();
+    llvm::Value *Elt = EmitScalarConversion(Src, SrcType, EltTy);
+
+    // Insert the element in element zero of an undef vector
+    llvm::Value *UnV = llvm::UndefValue::get(DstTy);
+    llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
+    UnV = Builder.CreateInsertElement(UnV, Elt, Idx, "tmp");
+
+    // Splat the element across to all elements
+    llvm::SmallVector<llvm::Constant*, 16> Args;
+    unsigned NumElements = cast<llvm::VectorType>(DstTy)->getNumElements();
+    for (unsigned i = 0; i < NumElements; i++)
+      Args.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, 0));
+    
+    llvm::Constant *Mask = llvm::ConstantVector::get(&Args[0], NumElements);
+    llvm::Value *Yay = Builder.CreateShuffleVector(UnV, UnV, Mask, "splat");
+    return Yay;
+  }
 
   // Allow bitcast from vector to integer/fp of the same size.
   if (isa<llvm::VectorType>(Src->getType()) ||