Author: bruno
Date: Fri Sep 30 17:19:38 2016
New Revision: 282968

URL: http://llvm.org/viewvc/llvm-project?rev=282968&view=rev
Log:
[Sema] Support lax conversions for compound assignments

Support lax convertions on compound assignment expressions 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 c = 3.0;
  float64x2_t v = {0.0, 1.0};
  c += vget_low_f64(v);

This restores one more valid behavior pre r266366, and is a incremental
follow up from work committed in r274646.

While here, make the check more strict, add FIXMEs, clean up variable
names to match what they can actually be and update testcases to reflect
that. We now reject:

  typedef float float2 __attribute__ ((vector_size (8)));
  double d;
  f2 += d;

which doesn't fit as a direct bitcast anyway.

Differential Revision: https://reviews.llvm.org/D24472

rdar://problem/28033929

Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/Sema/vector-cast.c

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=282968&r1=282967&r2=282968&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Sep 30 17:19:38 2016
@@ -8052,6 +8052,7 @@ QualType Sema::CheckVectorOperands(ExprR
 
   // If there's an ext-vector type and a scalar, try to convert the scalar to
   // the vector element type and splat.
+  // FIXME: this should also work for regular vector types as supported in GCC.
   if (!RHSVecType && isa<ExtVectorType>(LHSVecType)) {
     if (!tryVectorConvertAndSplat(*this, &RHS, RHSType,
                                   LHSVecType->getElementType(), LHSType))
@@ -8064,16 +8065,31 @@ QualType Sema::CheckVectorOperands(ExprR
       return RHSType;
   }
 
-  // If we're allowing lax vector conversions, only the total (data) size needs
-  // to be the same. If one of the types is scalar, the result is always the
-  // vector type. Don't allow this if the scalar operand is an lvalue.
+  // FIXME: The code below also handles convertion between vectors and
+  // non-scalars, we should break this down into fine grained specific checks
+  // and emit proper diagnostics.
   QualType VecType = LHSVecType ? LHSType : RHSType;
-  QualType ScalarType = LHSVecType ? RHSType : LHSType;
-  ExprResult *ScalarExpr = LHSVecType ? &RHS : &LHS;
-  if (isLaxVectorConversion(ScalarType, VecType) &&
-      !ScalarExpr->get()->isLValue()) {
-    *ScalarExpr = ImpCastExprToType(ScalarExpr->get(), VecType, CK_BitCast);
-    return VecType;
+  const VectorType *VT = LHSVecType ? LHSVecType : RHSVecType;
+  QualType OtherType = LHSVecType ? RHSType : LHSType;
+  ExprResult *OtherExpr = LHSVecType ? &RHS : &LHS;
+  if (isLaxVectorConversion(OtherType, VecType)) {
+    // If we're allowing lax vector conversions, only the total (data) size
+    // needs to be the same. For non compound assignment, if one of the types 
is
+    // scalar, the result is always the vector type.
+    if (!IsCompAssign) {
+      *OtherExpr = ImpCastExprToType(OtherExpr->get(), VecType, CK_BitCast);
+      return VecType;
+    // In a compound assignment, lhs += rhs, 'lhs' is a lvalue src, forbidding
+    // any implicit cast. Here, the 'rhs' should be implicit casted to 'lhs'
+    // type. Note that this is already done by non-compound assignments in
+    // CheckAssignmentConstraints. If it's a scalar type, only bitcast for
+    // <1 x T> -> T. The result is also a vector type.
+    } else if (OtherType->isExtVectorType() ||
+               (OtherType->isScalarType() && VT->getNumElements() == 1)) {
+      ExprResult *RHSExpr = &RHS;
+      *RHSExpr = ImpCastExprToType(RHSExpr->get(), LHSType, CK_BitCast);
+      return VecType;
+    }
   }
 
   // Okay, the expression is invalid.

Modified: cfe/trunk/test/Sema/vector-cast.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vector-cast.c?rev=282968&r1=282967&r2=282968&view=diff
==============================================================================
--- cfe/trunk/test/Sema/vector-cast.c (original)
+++ cfe/trunk/test/Sema/vector-cast.c Fri Sep 30 17:19:38 2016
@@ -53,14 +53,13 @@ void f4() {
   float2 f2;
   double d, a, b, c;
   float64x2_t v = {0.0, 1.0};
-  f2 += d;
+  // FIXME: These diagnostics are inaccurate: should complain that 'double' to 
vector 'float2' involves truncation
+  f2 += d; // expected-error {{cannot convert between vector values of 
different size ('float2' (vector of 2 'float' values) and 'double')}}
+  d += f2; // expected-error {{cannot convert between vector values of 
different size}}
   a = 3.0 + vget_low_f64(v);
   b = vget_low_f64(v) + 3.0;
   c = vget_low_f64(v);
-  // LAX conversions within compound assignments are not supported.
-  // FIXME: This diagnostic is inaccurate.
-  d += f2; // expected-error {{cannot convert between vector values of 
different size}}
-  c -= vget_low_f64(v); // expected-error {{cannot convert between vector 
values of different size}}
+  c -= vget_low_f64(v);
   // LAX conversions between scalar and vector types require same size and one 
element sized vectors.
   d = f2; // expected-error {{assigning to 'double' from incompatible type 
'float2'}}
   d = d + f2; // expected-error {{assigning to 'double' from incompatible type 
'float2'}}


_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to