bruno created this revision. bruno added reviewers: rnk, rsmith. bruno added a subscriber: cfe-commits.
Before r266366, clang used to support constructs like: typedef __attribute__((vector_size(8))) double float64x1_t; typedef __attribute__((vector_size(16))) double float64x2_t; float64x1_t vget_low_f64(float64x2_t __p0); double y = 3.0 + vget_low_f64(v); But it would reject: double y = vget_low_f64(v) + 3.0; It also always rejected assignments: double y = vget_low_f64(v); This patch: (a) revivies the behavior of `3.0 + vget_low_f64(v)` prior to r266366, (b) add support for `vget_low_f64(v) + 3.0` and (c) add support for assignments. These vector semantics have never really been tied up but it seems odd that we used to support some binop froms but do not support assignment. If we did support scalar for the purposes of arithmetic, we should probably be able to reinterpret as scalar for the purposes of assignment too. http://reviews.llvm.org/D21700 Files: lib/Sema/SemaExpr.cpp test/Sema/vector-cast.c 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 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 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; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits