[PATCH] D24472: [Sema] Support lax conversions for compound assignments

Bruno Cardoso Lopes via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 19 13:01:53 PDT 2016


bruno updated this revision to Diff 71870.
bruno added a comment.

Update again (now with the right patch) after Akira's comment


https://reviews.llvm.org/D24472

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
@@ -53,14 +53,13 @@
   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'}}
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -8051,6 +8051,7 @@
 
   // 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))
@@ -8063,16 +8064,31 @@
       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 biscast 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.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D24472.71870.patch
Type: text/x-patch
Size: 3926 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160919/82c61cc0/attachment-0001.bin>


More information about the cfe-commits mailing list