Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -7399,6 +7399,18 @@ return IncompatibleVectors; } } + + // When the RHS comes from another lax conversion (e.g. binops between + // scalars and vectors) the result is canonicalized as a vector. When the + // LHS is also a vector, the lax is allowed by the condition above. Handle + // the case where LHS is a scalar. + if (LHSType->isScalarType() && isLaxVectorConversion(RHSType, LHSType)) { + ExprResult *VecExpr = &RHS; + *VecExpr = ImpCastExprToType(VecExpr->get(), LHSType, CK_BitCast); + Kind = CK_BitCast; + return Compatible; + } + return Incompatible; } Index: test/Sema/vector-cast.c =================================================================== --- test/Sema/vector-cast.c +++ test/Sema/vector-cast.c @@ -45,17 +45,24 @@ } typedef float float2 __attribute__ ((vector_size (8))); +typedef __attribute__((vector_size(8))) double float64x1_t; +typedef __attribute__((vector_size(16))) double float64x2_t; +float64x1_t vget_low_f64(float64x2_t __p0); void f4() { float2 f2; - double d; + double d, a, b, c; + float64x2_t v = {0.0, 1.0}; f2 += d; - // We used to allow the next statement, but we've always rejected the next two - // statements + a = 3.0 + vget_low_f64(v); + b = vget_low_f64(v) + 3.0; + c = vget_low_f64(v); + // Compound assignments are not supported. // FIXME: This diagnostic is inaccurate. d += f2; // expected-error {{cannot convert between vector values of different size}} - d = f2; // expected-error {{assigning to 'double' from incompatible type 'float2'}} - d = d + f2; // expected-error {{assigning to 'double' from incompatible type 'float2'}} + c -= vget_low_f64(v); // expected-error {{cannot convert between vector values of different size}} + d = f2; + d = d + f2; } // rdar://15931426