Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp	(revision 204846)
+++ lib/Sema/SemaChecking.cpp	(working copy)
@@ -5750,6 +5750,8 @@
     Source = cast<VectorType>(Source)->getElementType().getTypePtr();
     Target = cast<VectorType>(Target)->getElementType().getTypePtr();
   }
+  if (isa<VectorType>(Target))
+    Target = cast<VectorType>(Target)->getElementType().getTypePtr();
 
   // Strip complex types.
   if (isa<ComplexType>(Source)) {
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp	(revision 204846)
+++ lib/Sema/SemaExpr.cpp	(working copy)
@@ -6696,13 +6696,12 @@
   return QualType();
 }
 
-/// Try to convert a value of non-vector type to a vector type by
-/// promoting (and only promoting) the type to the element type of the
-/// vector and then performing a vector splat.
+/// Try to convert a value of non-vector type to a vector type by converting
+/// the type to the element type of the vector and then performing a splat.
 ///
 /// \param scalar - if non-null, actually perform the conversions
 /// \return true if the operation fails (but without diagnosing the failure)
-static bool tryVectorPromoteAndSplat(Sema &S, ExprResult *scalar,
+static bool tryVectorConvertAndSplat(Sema &S, ExprResult *scalar,
                                      QualType scalarTy,
                                      QualType vectorEltTy,
                                      QualType vectorTy) {
@@ -6712,14 +6711,10 @@
 
   if (vectorEltTy->isIntegralType(S.Context)) {
     if (!scalarTy->isIntegralType(S.Context)) return true;
-    int order = S.Context.getIntegerTypeOrder(vectorEltTy, scalarTy);
-    if (order < 0) return true;
-    if (order > 0) scalarCast = CK_IntegralCast;
+        scalarCast = CK_IntegralCast;
   } else if (vectorEltTy->isRealFloatingType()) {
     if (scalarTy->isRealFloatingType()) {
-      int order = S.Context.getFloatingTypeOrder(vectorEltTy, scalarTy);
-      if (order < 0) return true;
-      if (order > 0) scalarCast = CK_FloatingCast;
+        scalarCast = CK_FloatingCast;
     } else if (scalarTy->isIntegralType(S.Context)) {
       scalarCast = CK_IntegralToFloating;
     } else {
@@ -6732,7 +6727,7 @@
   // Adjust scalar if desired.
   if (scalar) {
     if (scalarCast != CK_Invalid)
-       *scalar = S.ImpCastExprToType(scalar->take(), vectorEltTy, scalarCast);
+      *scalar = S.ImpCastExprToType(scalar->take(), vectorEltTy, scalarCast);
     *scalar = S.ImpCastExprToType(scalar->take(), vectorTy, CK_VectorSplat);
   }
   return false;
@@ -6775,6 +6770,19 @@
     return RHSType;
   }
 
+  // If there's an ext-vector type and a scalar, try to promote (and
+  // only promote) and splat the scalar to the vector type.
+  if (!RHSVecType && isa<ExtVectorType>(LHSVecType)) {
+    if (!tryVectorConvertAndSplat(*this, &RHS, RHSType,
+                                  LHSVecType->getElementType(), LHSType))
+      return LHSType;
+    }
+  if (!LHSVecType && isa<ExtVectorType>(RHSVecType)) {
+    if (!tryVectorConvertAndSplat(*this, (IsCompAssign ? 0 : &LHS), LHSType,
+                                  RHSVecType->getElementType(), RHSType))
+      return RHSType;
+    }
+
   // If we're allowing lax vector conversions, only the total (data) size
   // needs to be the same.
   // FIXME: Should we really be allowing this?
@@ -6785,19 +6793,6 @@
     return resultType;
   }
 
-  // If there's an ext-vector type and a scalar, try to promote (and
-  // only promote) and splat the scalar to the vector type.
-  if (!RHSVecType && isa<ExtVectorType>(LHSVecType)) {
-    if (!tryVectorPromoteAndSplat(*this, &RHS, RHSType,
-                                  LHSVecType->getElementType(), LHSType))
-      return LHSType;
-  }
-  if (!LHSVecType && isa<ExtVectorType>(RHSVecType)) {
-    if (!tryVectorPromoteAndSplat(*this, (IsCompAssign ? 0 : &LHS), LHSType,
-                                  RHSVecType->getElementType(), RHSType))
-      return RHSType;
-  }
-
   // Okay, the expression is invalid.
 
   // If there's a non-vector, non-real operand, diagnose that.
Index: test/Sema/ext_vector_casts.c
===================================================================
--- test/Sema/ext_vector_casts.c	(revision 204846)
+++ test/Sema/ext_vector_casts.c	(working copy)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -fsyntax-only -verify -fno-lax-vector-conversions %s
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -fsyntax-only -verify -fno-lax-vector-conversions -Wconversion %s
 
 typedef __attribute__(( ext_vector_type(2) )) float float2;
 typedef __attribute__(( ext_vector_type(3) )) float float3;
@@ -39,8 +39,7 @@
     
     vec4 = (float4)vec2; // expected-error {{invalid conversion between ext-vector type 'float4' and 'float2'}}
     
-    ish8 += 5; // expected-error {{can't convert between vector values of different size ('short8' and 'int')}}
-    ish8 += (short)5;
+    ish8 += 5;
     ivec4 *= 5;
      vec4 /= 5.2f;
      vec4 %= 4; // expected-error {{invalid operands to binary expression ('float4' and 'int')}}
@@ -89,3 +88,37 @@
 C3DVector3 Func(const C3DVector3 a) {
     return (C3DVector3)vabsq_f32((float32x4_t)a); // expected-error {{invalid conversion between ext-vector type 'float32x4_t' and 'C3DVector3'}}
 }
+
+// rdar://16350802
+typedef double double2 __attribute__ ((ext_vector_type(2)));
+
+static void splats(int i, long l, __uint128_t t, float f, double d) {
+    short8 vs = 0;
+    int4 vi = i;
+    ulong2 vl = (unsigned long)l;
+    float2 vf = f;
+    double2 vd = d;
+
+    vs = 65536 + vs; // expected-warning {{implicit conversion from 'int' to 'short8' changes value from 65536 to 0}}
+    vs = vs + i; // expected-warning {{implicit conversion loses integer precision}}
+    vs = vs + 1;
+    vs = vs + 1.f; // expected-error {{can't convert between vector values of different size}}
+
+    vi = l + vi; // expected-warning {{implicit conversion loses integer precision}}
+    vi = 1 + vi;
+    vi = vi + 2.0; // expected-error {{can't convert between vector values of different size}}
+    vi = vi + 0xffffffff; // expected-warning {{implicit conversion changes signedness}}
+
+    vl = l + vl; // expected-warning {{implicit conversion changes signedness}}
+    vl = vl + t; // expected-warning {{implicit conversion loses integer precision}}
+
+    vf = 1 + vf;
+    vf = l + vf;
+    vf = 2.0 + vf;
+    vf = d + vf; // expected-warning {{implicit conversion loses floating-point precision}}
+    vf = vf + 0xffffffff;
+    vf = vf + 2.1; // expected-warning {{implicit conversion loses floating-point precision}}
+    
+    vd = l + vd;
+    vd = vd + t;
+}
