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

Update patch after Reid's suggestions.

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,15 +45,23 @@
 }
 
 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);
+  // 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}}
+  // 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
@@ -7394,6 +7394,22 @@
         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()) {
+      const VectorType *VecType = RHSType->getAs<VectorType>();
+      if (VecType && VecType->getNumElements() == 1 &&
+          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,15 +45,23 @@
 }
 
 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);
+  // 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}}
+  // 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
@@ -7394,6 +7394,22 @@
         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()) {
+      const VectorType *VecType = RHSType->getAs<VectorType>();
+      if (VecType && VecType->getNumElements() == 1 &&
+          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

Reply via email to