[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-05-15 Thread Simon Dardis via Phabricator via cfe-commits
sdardis added a comment.

Thanks for the review.


Repository:
  rL LLVM

https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-05-12 Thread Simon Dardis via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL302935: [Sema] Support implicit scalar to vector conversions 
(authored by sdardis).

Changed prior to commit:
  https://reviews.llvm.org/D25866?vs=98783=98815#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D25866

Files:
  cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
  cfe/trunk/include/clang/Sema/Sema.h
  cfe/trunk/lib/Sema/SemaExpr.cpp
  cfe/trunk/lib/Sema/SemaExprCXX.cpp
  cfe/trunk/test/Sema/vector-cast.c
  cfe/trunk/test/Sema/vector-gcc-compat.c
  cfe/trunk/test/Sema/vector-gcc-compat.cpp
  cfe/trunk/test/Sema/vector-ops.c
  cfe/trunk/test/Sema/zvector.c
  cfe/trunk/test/SemaCXX/vector-no-lax.cpp

Index: cfe/trunk/lib/Sema/SemaExpr.cpp
===
--- cfe/trunk/lib/Sema/SemaExpr.cpp
+++ cfe/trunk/lib/Sema/SemaExpr.cpp
@@ -8031,6 +8031,33 @@
   return QualType();
 }
 
+// Diagnose cases where a scalar was implicitly converted to a vector and
+// diagnose the underlying types. Otherwise, diagnose the error
+// as invalid vector logical operands for non-C++ cases.
+QualType Sema::InvalidLogicalVectorOperands(SourceLocation Loc, ExprResult ,
+ExprResult ) {
+  QualType LHSType = LHS.get()->IgnoreImpCasts()->getType();
+  QualType RHSType = RHS.get()->IgnoreImpCasts()->getType();
+
+  bool LHSNatVec = LHSType->isVectorType();
+  bool RHSNatVec = RHSType->isVectorType();
+
+  if (!(LHSNatVec && RHSNatVec)) {
+Expr *Vector = LHSNatVec ? LHS.get() : RHS.get();
+Expr *NonVector = !LHSNatVec ? LHS.get() : RHS.get();
+Diag(Loc, diag::err_typecheck_logical_vector_expr_gnu_cpp_restrict)
+<< 0 << Vector->getType() << NonVector->IgnoreImpCasts()->getType()
+<< Vector->getSourceRange();
+return QualType();
+  }
+
+  Diag(Loc, diag::err_typecheck_logical_vector_expr_gnu_cpp_restrict)
+  << 1 << LHSType << RHSType << LHS.get()->getSourceRange()
+  << RHS.get()->getSourceRange();
+
+  return QualType();
+}
+
 /// Try to convert a value of non-vector type to a vector type by converting
 /// the type to the element type of the vector and then performing a splat.
 /// If the language is OpenCL, we only use conversions that promote scalar
@@ -8078,6 +8105,162 @@
   return false;
 }
 
+/// Test if a (constant) integer Int can be casted to another integer type
+/// IntTy without losing precision.
+static bool canConvertIntToOtherIntTy(Sema , ExprResult *Int,
+  QualType OtherIntTy) {
+  QualType IntTy = Int->get()->getType().getUnqualifiedType();
+
+  // Reject cases where the value of the Int is unknown as that would
+  // possibly cause truncation, but accept cases where the scalar can be
+  // demoted without loss of precision.
+  llvm::APSInt Result;
+  bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context);
+  int Order = S.Context.getIntegerTypeOrder(OtherIntTy, IntTy);
+  bool IntSigned = IntTy->hasSignedIntegerRepresentation();
+  bool OtherIntSigned = OtherIntTy->hasSignedIntegerRepresentation();
+
+  if (CstInt) {
+// If the scalar is constant and is of a higher order and has more active
+// bits that the vector element type, reject it.
+unsigned NumBits = IntSigned
+   ? (Result.isNegative() ? Result.getMinSignedBits()
+  : Result.getActiveBits())
+   : Result.getActiveBits();
+if (Order < 0 && S.Context.getIntWidth(OtherIntTy) < NumBits)
+  return true;
+
+// If the signedness of the scalar type and the vector element type
+// differs and the number of bits is greater than that of the vector
+// element reject it.
+return (IntSigned != OtherIntSigned &&
+NumBits > S.Context.getIntWidth(OtherIntTy));
+  }
+
+  // Reject cases where the value of the scalar is not constant and it's
+  // order is greater than that of the vector element type.
+  return (Order < 0);
+}
+
+/// Test if a (constant) integer Int can be casted to floating point type
+/// FloatTy without losing precision.
+static bool canConvertIntTyToFloatTy(Sema , ExprResult *Int,
+ QualType FloatTy) {
+  QualType IntTy = Int->get()->getType().getUnqualifiedType();
+
+  // Determine if the integer constant can be expressed as a floating point
+  // number of the appropiate type.
+  llvm::APSInt Result;
+  bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context);
+  uint64_t Bits = 0;
+  if (CstInt) {
+// Reject constants that would be truncated if they were converted to
+// the floating point type. Test by simple to/from conversion.
+// FIXME: Ideally the conversion to an APFloat and from an APFloat
+//could be avoided if there was a convertFromAPInt method
+//which could signal back if implicit truncation occurred.
+llvm::APFloat 

[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-05-12 Thread Simon Dardis via Phabricator via cfe-commits
sdardis updated this revision to Diff 98783.
sdardis marked an inline comment as done.
sdardis edited the summary of this revision.
sdardis added a comment.

Updated error message for logical operations where one operand is a vector and 
the other isn't.

Updated summary.

I'll commit this shortly.


https://reviews.llvm.org/D25866

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaExprCXX.cpp
  test/Sema/vector-cast.c
  test/Sema/vector-gcc-compat.c
  test/Sema/vector-gcc-compat.cpp
  test/Sema/vector-ops.c
  test/Sema/zvector.c
  test/SemaCXX/vector-no-lax.cpp

Index: test/SemaCXX/vector-no-lax.cpp
===
--- test/SemaCXX/vector-no-lax.cpp
+++ test/SemaCXX/vector-no-lax.cpp
@@ -4,6 +4,6 @@
 
 vSInt32 foo (vUInt32 a) {
   vSInt32 b = { 0, 0, 0, 0 };
-  b += a; // expected-error{{cannot convert between vector values}}
+  b += a; // expected-error{{cannot convert between vector type 'vUInt32' (vector of 4 'unsigned int' values) and vector type 'vSInt32' (vector of 4 'int' values) as implicit conversion would cause truncation}}
   return b;
 }
Index: test/Sema/zvector.c
===
--- test/Sema/zvector.c
+++ test/Sema/zvector.c
@@ -326,14 +326,14 @@
   bc = bc + sc2; // expected-error {{incompatible type}}
   bc = sc + bc2; // expected-error {{incompatible type}}
 
-  sc = sc + sc_scalar; // expected-error {{cannot convert}}
-  sc = sc + uc_scalar; // expected-error {{cannot convert}}
-  sc = sc_scalar + sc; // expected-error {{cannot convert}}
-  sc = uc_scalar + sc; // expected-error {{cannot convert}}
-  uc = uc + sc_scalar; // expected-error {{cannot convert}}
-  uc = uc + uc_scalar; // expected-error {{cannot convert}}
-  uc = sc_scalar + uc; // expected-error {{cannot convert}}
-  uc = uc_scalar + uc; // expected-error {{cannot convert}}
+  sc = sc + sc_scalar;
+  sc = sc + uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  sc = sc_scalar + sc;
+  sc = uc_scalar + sc; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc = uc + sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc + uc_scalar;
+  uc = sc_scalar + uc; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc_scalar + uc;
 
   ss = ss + ss2;
   us = us + us2;
@@ -368,10 +368,10 @@
   sc += sl2; // expected-error {{cannot convert}}
   sc += fd2; // expected-error {{cannot convert}}
 
-  sc += sc_scalar; // expected-error {{cannot convert}}
-  sc += uc_scalar; // expected-error {{cannot convert}}
-  uc += sc_scalar; // expected-error {{cannot convert}}
-  uc += uc_scalar; // expected-error {{cannot convert}}
+  sc += sc_scalar;
+  sc += uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc += sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc += uc_scalar;
 
   ss += ss2;
   us += us2;
Index: test/Sema/vector-ops.c
===
--- test/Sema/vector-ops.c
+++ test/Sema/vector-ops.c
@@ -13,11 +13,11 @@
   (void)(~v2fa); // expected-error{{invalid argument type 'v2f' (vector of 2 'float' values) to unary}}
 
   // Comparison operators
-  v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int int' (vector of 2 'int' values)}}
+  v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int int' (vector of 2 'int' values}}
   v2sa = (v2ua==v2sa);
 
   // Arrays
-  int array1[v2ua]; // expected-error{{size of array has non-integer type 'v2u' (vector of 2 'unsigned int' values)}}
+  int array1[v2ua]; // expected-error{{size of array has non-integer type 'v2u' (vector of 2 'unsigned int' values}}
   int array2[17];
   // FIXME: error message below needs type!
   (void)(array2[v2ua]); // expected-error{{array subscript is not an integer}}
@@ -28,108 +28,108 @@
 }
 
 void testLogicalVecVec(v2u v2ua, v2s v2sa, v2f v2fa) {
-
   // Logical operators
-  v2ua = v2ua && v2ua; // expected-warning {{incompatible vector types 

[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-04-26 Thread Bruno Cardoso Lopes via Phabricator via cfe-commits
bruno accepted this revision.
bruno added a comment.
This revision is now accepted and ready to land.

Thanks for your patience! LGTM with a minor comment below.




Comment at: test/Sema/vector-gcc-compat.c:101
+
+  v2i64_r = v2i64_a && 1; // expected-error {{invalid vector operand to binary 
expression ('v2i64' (vector of 2 'long long' values))}}
+  v2i64_r = v2i64_a || 1; // expected-error {{invalid vector operand to binary 
expression ('v2i64' (vector of 2 'long long' values))}}

sdardis wrote:
> bruno wrote:
> > Is this because of && and others only working in C++? If so, we need a 
> > better error message here, along the lines of "logical expression with 
> > vector only support in C++". If later on we decide to support it in 
> > non-C++, we then get rid of the warning.
> > 
> > 
> > 
> Yes, these operators are oddly only available in C++.
> 
> I've changed the error message to "logical expression with vector type[s] 
> '' (vector of  '' values) [and ' type>'] is only supported in C++".
Great, can you also mention the type of the other hand side when it's not a 
vector?


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-04-25 Thread Simon Dardis via Phabricator via cfe-commits
sdardis updated this revision to Diff 96533.
sdardis added a comment.

Rebase + ping.


https://reviews.llvm.org/D25866

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaExprCXX.cpp
  test/Sema/vector-cast.c
  test/Sema/vector-gcc-compat.c
  test/Sema/vector-gcc-compat.cpp
  test/Sema/vector-ops.c
  test/Sema/zvector.c
  test/SemaCXX/vector-no-lax.cpp

Index: test/SemaCXX/vector-no-lax.cpp
===
--- test/SemaCXX/vector-no-lax.cpp
+++ test/SemaCXX/vector-no-lax.cpp
@@ -4,6 +4,6 @@
 
 vSInt32 foo (vUInt32 a) {
   vSInt32 b = { 0, 0, 0, 0 };
-  b += a; // expected-error{{cannot convert between vector values}}
+  b += a; // expected-error{{cannot convert between vector type 'vUInt32' (vector of 4 'unsigned int' values) and vector type 'vSInt32' (vector of 4 'int' values) as implicit conversion would cause truncation}}
   return b;
 }
Index: test/Sema/zvector.c
===
--- test/Sema/zvector.c
+++ test/Sema/zvector.c
@@ -326,14 +326,14 @@
   bc = bc + sc2; // expected-error {{incompatible type}}
   bc = sc + bc2; // expected-error {{incompatible type}}
 
-  sc = sc + sc_scalar; // expected-error {{cannot convert}}
-  sc = sc + uc_scalar; // expected-error {{cannot convert}}
-  sc = sc_scalar + sc; // expected-error {{cannot convert}}
-  sc = uc_scalar + sc; // expected-error {{cannot convert}}
-  uc = uc + sc_scalar; // expected-error {{cannot convert}}
-  uc = uc + uc_scalar; // expected-error {{cannot convert}}
-  uc = sc_scalar + uc; // expected-error {{cannot convert}}
-  uc = uc_scalar + uc; // expected-error {{cannot convert}}
+  sc = sc + sc_scalar;
+  sc = sc + uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  sc = sc_scalar + sc;
+  sc = uc_scalar + sc; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc = uc + sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc + uc_scalar;
+  uc = sc_scalar + uc; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc_scalar + uc;
 
   ss = ss + ss2;
   us = us + us2;
@@ -368,10 +368,10 @@
   sc += sl2; // expected-error {{cannot convert}}
   sc += fd2; // expected-error {{cannot convert}}
 
-  sc += sc_scalar; // expected-error {{cannot convert}}
-  sc += uc_scalar; // expected-error {{cannot convert}}
-  uc += sc_scalar; // expected-error {{cannot convert}}
-  uc += uc_scalar; // expected-error {{cannot convert}}
+  sc += sc_scalar;
+  sc += uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc += sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc += uc_scalar;
 
   ss += ss2;
   us += us2;
Index: test/Sema/vector-ops.c
===
--- test/Sema/vector-ops.c
+++ test/Sema/vector-ops.c
@@ -13,11 +13,11 @@
   (void)(~v2fa); // expected-error{{invalid argument type 'v2f' (vector of 2 'float' values) to unary}}
 
   // Comparison operators
-  v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int int' (vector of 2 'int' values)}}
+  v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int int' (vector of 2 'int' values}}
   v2sa = (v2ua==v2sa);
 
   // Arrays
-  int array1[v2ua]; // expected-error{{size of array has non-integer type 'v2u' (vector of 2 'unsigned int' values)}}
+  int array1[v2ua]; // expected-error{{size of array has non-integer type 'v2u' (vector of 2 'unsigned int' values}}
   int array2[17];
   // FIXME: error message below needs type!
   (void)(array2[v2ua]); // expected-error{{array subscript is not an integer}}
@@ -28,108 +28,108 @@
 }
 
 void testLogicalVecVec(v2u v2ua, v2s v2sa, v2f v2fa) {
-
   // Logical operators
-  v2ua = v2ua && v2ua; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int int' (vector of 2 'int' values)}}
-  v2ua = v2ua || v2ua; // expected-warning {{incompatible vector 

[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-04-18 Thread Simon Dardis via Phabricator via cfe-commits
sdardis added a comment.

Realised I've some comments to submit.




Comment at: lib/Sema/SemaExpr.cpp:8032
+
+  return InvalidOperands(Loc, LHS, RHS);
+}

bruno wrote:
> Double checking here: are there tests for the `InvalidOperands` case above?
Yes, this case is covered in the new diff in test/Sema/vector-ops.c and in 
test/Sema/vector-gcc-compat.c . 



Comment at: lib/Sema/SemaExpr.cpp:10024
+  // FIXME: The check for C++ here is for GCC compatibility. GCC rejects the
+  //usage of logical operators with vectors in C. This check could be
+  //notionally dropped.

bruno wrote:
> Please mention in the comment the list of logical ops that this applies to: 
> "!, &&, ||"
I've updated the relevant Check* functions with FIXME:s noting that they should 
handle vector types for compatibility with GCC.



Comment at: test/Sema/vector-gcc-compat.c:101
+
+  v2i64_r = v2i64_a && 1; // expected-error {{invalid vector operand to binary 
expression ('v2i64' (vector of 2 'long long' values))}}
+  v2i64_r = v2i64_a || 1; // expected-error {{invalid vector operand to binary 
expression ('v2i64' (vector of 2 'long long' values))}}

bruno wrote:
> Is this because of && and others only working in C++? If so, we need a better 
> error message here, along the lines of "logical expression with vector only 
> support in C++". If later on we decide to support it in non-C++, we then get 
> rid of the warning.
> 
> 
> 
Yes, these operators are oddly only available in C++.

I've changed the error message to "logical expression with vector type[s] 
'' (vector of  '' values) [and ''] 
is only supported in C++".


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-04-13 Thread Simon Dardis via Phabricator via cfe-commits
sdardis updated this revision to Diff 95109.
sdardis marked 2 inline comments as done.
sdardis added a comment.

Addressed review comments. I've highlighted the relevant places with FIXME:s 
where we don't support GCC vector operations.


https://reviews.llvm.org/D25866

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaExprCXX.cpp
  test/Sema/vector-cast.c
  test/Sema/vector-gcc-compat.c
  test/Sema/vector-gcc-compat.cpp
  test/Sema/vector-ops.c
  test/Sema/zvector.c
  test/SemaCXX/vector-no-lax.cpp

Index: test/SemaCXX/vector-no-lax.cpp
===
--- test/SemaCXX/vector-no-lax.cpp
+++ test/SemaCXX/vector-no-lax.cpp
@@ -4,6 +4,6 @@
 
 vSInt32 foo (vUInt32 a) {
   vSInt32 b = { 0, 0, 0, 0 };
-  b += a; // expected-error{{cannot convert between vector values}}
+  b += a; // expected-error{{cannot convert between vector type 'vUInt32' (vector of 4 'unsigned int' values) and vector type 'vSInt32' (vector of 4 'int' values) as implicit conversion would cause truncation}}
   return b;
 }
Index: test/Sema/zvector.c
===
--- test/Sema/zvector.c
+++ test/Sema/zvector.c
@@ -326,14 +326,14 @@
   bc = bc + sc2; // expected-error {{incompatible type}}
   bc = sc + bc2; // expected-error {{incompatible type}}
 
-  sc = sc + sc_scalar; // expected-error {{cannot convert}}
-  sc = sc + uc_scalar; // expected-error {{cannot convert}}
-  sc = sc_scalar + sc; // expected-error {{cannot convert}}
-  sc = uc_scalar + sc; // expected-error {{cannot convert}}
-  uc = uc + sc_scalar; // expected-error {{cannot convert}}
-  uc = uc + uc_scalar; // expected-error {{cannot convert}}
-  uc = sc_scalar + uc; // expected-error {{cannot convert}}
-  uc = uc_scalar + uc; // expected-error {{cannot convert}}
+  sc = sc + sc_scalar;
+  sc = sc + uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  sc = sc_scalar + sc;
+  sc = uc_scalar + sc; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc = uc + sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc + uc_scalar;
+  uc = sc_scalar + uc; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc_scalar + uc;
 
   ss = ss + ss2;
   us = us + us2;
@@ -368,10 +368,10 @@
   sc += sl2; // expected-error {{cannot convert}}
   sc += fd2; // expected-error {{cannot convert}}
 
-  sc += sc_scalar; // expected-error {{cannot convert}}
-  sc += uc_scalar; // expected-error {{cannot convert}}
-  uc += sc_scalar; // expected-error {{cannot convert}}
-  uc += uc_scalar; // expected-error {{cannot convert}}
+  sc += sc_scalar;
+  sc += uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc += sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc += uc_scalar;
 
   ss += ss2;
   us += us2;
Index: test/Sema/vector-ops.c
===
--- test/Sema/vector-ops.c
+++ test/Sema/vector-ops.c
@@ -13,11 +13,11 @@
   (void)(~v2fa); // expected-error{{invalid argument type 'v2f' (vector of 2 'float' values) to unary}}
 
   // Comparison operators
-  v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int int' (vector of 2 'int' values)}}
+  v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int int' (vector of 2 'int' values}}
   v2sa = (v2ua==v2sa);
 
   // Arrays
-  int array1[v2ua]; // expected-error{{size of array has non-integer type 'v2u' (vector of 2 'unsigned int' values)}}
+  int array1[v2ua]; // expected-error{{size of array has non-integer type 'v2u' (vector of 2 'unsigned int' values}}
   int array2[17];
   // FIXME: error message below needs type!
   (void)(array2[v2ua]); // expected-error{{array subscript is not an integer}}
@@ -28,108 +28,108 @@
 }
 
 void testLogicalVecVec(v2u v2ua, v2s v2sa, v2f v2fa) {
-
   // Logical operators
-  v2ua = v2ua && v2ua; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from 

[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-04-10 Thread Bruno Cardoso Lopes via Phabricator via cfe-commits
bruno added inline comments.



Comment at: lib/Sema/SemaExpr.cpp:10024
+  // FIXME: The check for C++ here is for GCC compatibility. GCC rejects the
+  //usage of logical operators with vectors in C. This check could be
+  //notionally dropped.

Please mention in the comment the list of logical ops that this applies to: "!, 
&&, ||"



Comment at: test/Sema/vector-gcc-compat.c:101
+
+  v2i64_r = v2i64_a && 1; // expected-error {{invalid vector operand to binary 
expression ('v2i64' (vector of 2 'long long' values))}}
+  v2i64_r = v2i64_a || 1; // expected-error {{invalid vector operand to binary 
expression ('v2i64' (vector of 2 'long long' values))}}

Is this because of && and others only working in C++? If so, we need a better 
error message here, along the lines of "logical expression with vector only 
support in C++". If later on we decide to support it in non-C++, we then get 
rid of the warning.





https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-04-06 Thread Simon Dardis via Phabricator via cfe-commits
sdardis updated this revision to Diff 94434.
sdardis marked 7 inline comments as done.
sdardis added a comment.

Addressed review comments.

I've changed InvalidVectorOperands() to not use InvalidOperands() after 
updating some tests. InvalidOperands() was receiving expressions with implicit 
casts, leading to misleading error messages.


https://reviews.llvm.org/D25866

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaExpr.cpp
  test/Sema/vector-cast.c
  test/Sema/vector-gcc-compat.c
  test/Sema/vector-gcc-compat.cpp
  test/Sema/vector-ops.c
  test/Sema/zvector.c
  test/SemaCXX/vector-no-lax.cpp

Index: test/SemaCXX/vector-no-lax.cpp
===
--- test/SemaCXX/vector-no-lax.cpp
+++ test/SemaCXX/vector-no-lax.cpp
@@ -4,6 +4,6 @@
 
 vSInt32 foo (vUInt32 a) {
   vSInt32 b = { 0, 0, 0, 0 };
-  b += a; // expected-error{{cannot convert between vector values}}
+  b += a; // expected-error{{cannot convert between vector type 'vUInt32' (vector of 4 'unsigned int' values) and vector type 'vSInt32' (vector of 4 'int' values) as implicit conversion would cause truncation}}
   return b;
 }
Index: test/Sema/zvector.c
===
--- test/Sema/zvector.c
+++ test/Sema/zvector.c
@@ -326,14 +326,14 @@
   bc = bc + sc2; // expected-error {{incompatible type}}
   bc = sc + bc2; // expected-error {{incompatible type}}
 
-  sc = sc + sc_scalar; // expected-error {{cannot convert}}
-  sc = sc + uc_scalar; // expected-error {{cannot convert}}
-  sc = sc_scalar + sc; // expected-error {{cannot convert}}
-  sc = uc_scalar + sc; // expected-error {{cannot convert}}
-  uc = uc + sc_scalar; // expected-error {{cannot convert}}
-  uc = uc + uc_scalar; // expected-error {{cannot convert}}
-  uc = sc_scalar + uc; // expected-error {{cannot convert}}
-  uc = uc_scalar + uc; // expected-error {{cannot convert}}
+  sc = sc + sc_scalar;
+  sc = sc + uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  sc = sc_scalar + sc;
+  sc = uc_scalar + sc; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc = uc + sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc + uc_scalar;
+  uc = sc_scalar + uc; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc_scalar + uc;
 
   ss = ss + ss2;
   us = us + us2;
@@ -368,10 +368,10 @@
   sc += sl2; // expected-error {{cannot convert}}
   sc += fd2; // expected-error {{cannot convert}}
 
-  sc += sc_scalar; // expected-error {{cannot convert}}
-  sc += uc_scalar; // expected-error {{cannot convert}}
-  uc += sc_scalar; // expected-error {{cannot convert}}
-  uc += uc_scalar; // expected-error {{cannot convert}}
+  sc += sc_scalar;
+  sc += uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc += sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc += uc_scalar;
 
   ss += ss2;
   us += us2;
Index: test/Sema/vector-ops.c
===
--- test/Sema/vector-ops.c
+++ test/Sema/vector-ops.c
@@ -30,106 +30,108 @@
 void testLogicalVecVec(v2u v2ua, v2s v2sa, v2f v2fa) {
 
   // Logical operators
-  v2ua = v2ua && v2ua; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int int' (vector of 2 'int' values)}}
-  v2ua = v2ua || v2ua; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int int' (vector of 2 'int' values)}}
+  v2ua = v2ua && v2ua; // expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'v2u')}}
+  v2ua = v2ua || v2ua; // expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'v2u')}}
 
-  v2ua = v2sa && v2ua; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int int' (vector of 2 'int' values)}}
-  v2ua = v2sa || v2ua; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from 

[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-04-05 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak added inline comments.



Comment at: lib/Sema/SemaExpr.cpp:8024
+  bool RHSNatVec = RHS.get()->IgnoreImpCasts()->getType()->isVectorType();
+
+  if (LHSNatVec ^ RHSNatVec) {

I think "!=" is easier to understand than "^" here.



Comment at: lib/Sema/SemaExpr.cpp:8305
 
-  // If there's an ext-vector type and a scalar, try to convert the scalar to
+  // If there's an vector type and a scalar, try to convert the scalar to
   // the vector element type and splat.

"a vector"


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-04-05 Thread Bruno Cardoso Lopes via Phabricator via cfe-commits
bruno added inline comments.



Comment at: lib/Sema/SemaExpr.cpp:8188
+  //type and then perform the rest of the checks here. GCC as of
+  //pre-release 7.0 does not accept this though.
+  if (VectorEltTy->isIntegralType(S.Context) &&

sdardis wrote:
> bruno wrote:
> > Is this something that GCC is going to support at some point? Regardless of 
> > GCC, do we want this behavior?
> > Is this something that GCC is going to support at some point?
> 
> I've reread GCC's source for conversions of scalar to vectors types and it 
> appears that GCC does attempt to convert constant real expressions to 
> integers but it appears to only work for C++. It's a little odd.
> 
> > Regardless of GCC, do we want this behavior?
> 
> Given my oversight of the support of implicit safe conversions of floating 
> point constants to integer types, I believe we should do this in general. 
> I'll rework the comment to be more accurate and add the necessary conversion 
> checks.
Ok, improving the FIXME sounds good to me. We can add this extra functionality 
in a future patch.



Comment at: lib/Sema/SemaExpr.cpp:10019
   isa(vType->getAs()) || getLangOpts().OpenCL;
+  if ((!getLangOpts().CPlusPlus && !getLangOpts().OpenCL) && !isExtVectorType)
+return InvalidVectorOperands(Loc, LHS, RHS);

sdardis wrote:
> bruno wrote:
> > Why `!getLangOpts().CPlusPlus` is a requirement here?
> GCC only supports the logical operators &&, ||, ! when compiling C++.
> 
> It's noted near the bottom half of this page: 
> https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
Ok. It would be nice to find out if there's any actual good reason for it, 
otherwise we might as well support it for non C++. But no need to block on 
that; just make sure to annotate these places with FIXMEs so we can work on it 
in the future. 


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-04-05 Thread Simon Dardis via Phabricator via cfe-commits
sdardis marked an inline comment as done.
sdardis added a comment.

Thanks for sticking with this.

I've held off updating the diff until https://reviews.llvm.org/D31667 (not 
https://reviews.llvm.org/D31337 as previously posted) is finished. Responses 
inlined.




Comment at: lib/Sema/SemaExpr.cpp:8188
+  //type and then perform the rest of the checks here. GCC as of
+  //pre-release 7.0 does not accept this though.
+  if (VectorEltTy->isIntegralType(S.Context) &&

bruno wrote:
> Is this something that GCC is going to support at some point? Regardless of 
> GCC, do we want this behavior?
> Is this something that GCC is going to support at some point?

I've reread GCC's source for conversions of scalar to vectors types and it 
appears that GCC does attempt to convert constant real expressions to integers 
but it appears to only work for C++. It's a little odd.

> Regardless of GCC, do we want this behavior?

Given my oversight of the support of implicit safe conversions of floating 
point constants to integer types, I believe we should do this in general. I'll 
rework the comment to be more accurate and add the necessary conversion checks.



Comment at: lib/Sema/SemaExpr.cpp:10019
   isa(vType->getAs()) || getLangOpts().OpenCL;
+  if ((!getLangOpts().CPlusPlus && !getLangOpts().OpenCL) && !isExtVectorType)
+return InvalidVectorOperands(Loc, LHS, RHS);

bruno wrote:
> Why `!getLangOpts().CPlusPlus` is a requirement here?
GCC only supports the logical operators &&, ||, ! when compiling C++.

It's noted near the bottom half of this page: 
https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html



Comment at: test/Sema/vector-g++-compat.cpp:155
+   unsigned long long d) { // expected-warning {{'long 
long' is incompatible with C++98}}
+
+  v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};

bruno wrote:
> Remove all these extra new lines after the function signature here, in the 
> functions below and in the other added test file for c++.
Will do.


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-04-04 Thread Bruno Cardoso Lopes via Phabricator via cfe-commits
bruno added inline comments.



Comment at: lib/Sema/SemaExpr.cpp:8032
+
+  return InvalidOperands(Loc, LHS, RHS);
+}

Double checking here: are there tests for the `InvalidOperands` case above?



Comment at: lib/Sema/SemaExpr.cpp:8163
+/// type without causing truncation of Scalar.
+static bool tryGCCVectorConvertAndSpalt(Sema , ExprResult *Scalar,
+ExprResult *Vector) {

`Spalt` -> `Splat`



Comment at: lib/Sema/SemaExpr.cpp:8188
+  //type and then perform the rest of the checks here. GCC as of
+  //pre-release 7.0 does not accept this though.
+  if (VectorEltTy->isIntegralType(S.Context) &&

Is this something that GCC is going to support at some point? Regardless of 
GCC, do we want this behavior?



Comment at: lib/Sema/SemaExpr.cpp:10019
   isa(vType->getAs()) || getLangOpts().OpenCL;
+  if ((!getLangOpts().CPlusPlus && !getLangOpts().OpenCL) && !isExtVectorType)
+return InvalidVectorOperands(Loc, LHS, RHS);

Why `!getLangOpts().CPlusPlus` is a requirement here?



Comment at: test/Sema/vector-g++-compat.cpp:1
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything -std=c++11
+

Can you rename this file to `vector-gcc-compat.cpp` instead?



Comment at: test/Sema/vector-g++-compat.cpp:155
+   unsigned long long d) { // expected-warning {{'long 
long' is incompatible with C++98}}
+
+  v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};

Remove all these extra new lines after the function signature here, in the 
functions below and in the other added test file for c++.


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-04-04 Thread Simon Dardis via Phabricator via cfe-commits
sdardis updated this revision to Diff 94070.
sdardis added a comment.

Factored out the changes from https://reviews.llvm.org/D31337.


https://reviews.llvm.org/D25866

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaExpr.cpp
  test/Sema/vector-cast.c
  test/Sema/vector-g++-compat.cpp
  test/Sema/vector-gcc-compat.c
  test/Sema/zvector.c
  test/SemaCXX/vector-no-lax.cpp

Index: test/SemaCXX/vector-no-lax.cpp
===
--- test/SemaCXX/vector-no-lax.cpp
+++ test/SemaCXX/vector-no-lax.cpp
@@ -4,6 +4,6 @@
 
 vSInt32 foo (vUInt32 a) {
   vSInt32 b = { 0, 0, 0, 0 };
-  b += a; // expected-error{{cannot convert between vector values}}
+  b += a; // expected-error{{cannot convert between vector type 'vUInt32' (vector of 4 'unsigned int' values) and vector type 'vSInt32' (vector of 4 'int' values) as implicit conversion would cause truncation}}
   return b;
 }
Index: test/Sema/zvector.c
===
--- test/Sema/zvector.c
+++ test/Sema/zvector.c
@@ -326,14 +326,14 @@
   bc = bc + sc2; // expected-error {{incompatible type}}
   bc = sc + bc2; // expected-error {{incompatible type}}
 
-  sc = sc + sc_scalar; // expected-error {{cannot convert}}
-  sc = sc + uc_scalar; // expected-error {{cannot convert}}
-  sc = sc_scalar + sc; // expected-error {{cannot convert}}
-  sc = uc_scalar + sc; // expected-error {{cannot convert}}
-  uc = uc + sc_scalar; // expected-error {{cannot convert}}
-  uc = uc + uc_scalar; // expected-error {{cannot convert}}
-  uc = sc_scalar + uc; // expected-error {{cannot convert}}
-  uc = uc_scalar + uc; // expected-error {{cannot convert}}
+  sc = sc + sc_scalar;
+  sc = sc + uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  sc = sc_scalar + sc;
+  sc = uc_scalar + sc; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc = uc + sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc + uc_scalar;
+  uc = sc_scalar + uc; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc_scalar + uc;
 
   ss = ss + ss2;
   us = us + us2;
@@ -368,10 +368,10 @@
   sc += sl2; // expected-error {{cannot convert}}
   sc += fd2; // expected-error {{cannot convert}}
 
-  sc += sc_scalar; // expected-error {{cannot convert}}
-  sc += uc_scalar; // expected-error {{cannot convert}}
-  uc += sc_scalar; // expected-error {{cannot convert}}
-  uc += uc_scalar; // expected-error {{cannot convert}}
+  sc += sc_scalar;
+  sc += uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc += sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc += uc_scalar;
 
   ss += ss2;
   us += us2;
Index: test/Sema/vector-gcc-compat.c
===
--- /dev/null
+++ test/Sema/vector-gcc-compat.c
@@ -0,0 +1,335 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything
+
+// Test the compatibility of clang's vector extensions with gcc's vector
+// extensions for C. Notably &&, ||, ?: and ! are not available.
+typedef long long v2i64 __attribute__((vector_size(16)));
+typedef int v2i32 __attribute__((vector_size(8)));
+typedef short v2i16 __attribute__((vector_size(4)));
+typedef char v2i8 __attribute__((vector_size(2)));
+
+typedef unsigned long long v2u64 __attribute__((vector_size(16)));
+typedef unsigned int v2u32 __attribute__((vector_size(8)));
+typedef unsigned short v2u16 __attribute__((vector_size(4)));
+typedef unsigned char v2u8 __attribute__((vector_size(2)));
+
+typedef float v4f32 __attribute__((vector_size(16)));
+typedef double v2f64 __attribute__((vector_size(16)));
+typedef double v4f64 __attribute__((vector_size(32)));
+typedef int v4i32 __attribute((vector_size(16)));
+
+void arithmeticTest(void);
+void logicTest(void);
+void comparisonTest(void);
+void floatTestSignedType(char a, short b, int c, long long d);
+void floatTestUnsignedType(unsigned char a, unsigned short b, unsigned int c,
+   unsigned long long d);
+void floatTestConstant(void);
+void intTestType(char a, short b, int c, long long d);
+void intTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d);

[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-03-27 Thread Bruno Cardoso Lopes via Phabricator via cfe-commits
bruno added inline comments.



Comment at: test/Sema/vector-gcc-compat.c:61
+  //match.
+  v2i64_r = v2i64_a == 1; // expected-warning {{incompatible vector types 
assigning to 'v2i64' (vector of 2 'long long' values) from 'long 
__attribute__((ext_vector_type(2)))' (vector of 2 'long' values)}}
+  v2i64_r = v2i64_a != 1; // expected-warning {{incompatible vector types 
assigning to 'v2i64' (vector of 2 'long long' values) from 'long 
__attribute__((ext_vector_type(2)))' (vector of 2 'long' values)}}

sdardis wrote:
> bruno wrote:
> > Can you double check where 'long __attribute__((ext_vector_type(2)))' comes 
> > from?
> > 
> > We have regressed in the past year in the way ext-vector interacts with 
> > non-ext-vectors, and I don't wanna make it worse until we actually have 
> > time to fix that; there's a lot of code out there relying on bitcasts 
> > between ext-vectors and non-ext-vectors to bridge between intrinsics 
> > headers and ext-vector code.
> Sema::CheckVectorCompareOperands calls Sema::GetSignedVectorType which only 
> returns ext-vector types. I presume that is now incorrect if we're producing 
> vectors from literal scalars in the non OpenCL case.
Nice catch, can you please submit these specific changes as a separated patch 
and mark it as a prerequisite of this one?


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-03-14 Thread Simon Dardis via Phabricator via cfe-commits
sdardis updated this revision to Diff 91716.
sdardis added a comment.

Addressed review comments, add C++ specific test.


https://reviews.llvm.org/D25866

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaExpr.cpp
  test/Sema/vector-cast.c
  test/Sema/vector-g++-compat.cpp
  test/Sema/vector-gcc-compat.c
  test/Sema/vector-ops.c
  test/Sema/zvector.c
  test/SemaCXX/vector-no-lax.cpp

Index: test/SemaCXX/vector-no-lax.cpp
===
--- test/SemaCXX/vector-no-lax.cpp
+++ test/SemaCXX/vector-no-lax.cpp
@@ -4,6 +4,6 @@
 
 vSInt32 foo (vUInt32 a) {
   vSInt32 b = { 0, 0, 0, 0 };
-  b += a; // expected-error{{cannot convert between vector values}}
+  b += a; // expected-error{{cannot convert between vector type 'vUInt32' (vector of 4 'unsigned int' values) and vector type 'vSInt32' (vector of 4 'int' values) as implicit conversion would cause truncation}}
   return b;
 }
Index: test/Sema/zvector.c
===
--- test/Sema/zvector.c
+++ test/Sema/zvector.c
@@ -326,14 +326,14 @@
   bc = bc + sc2; // expected-error {{incompatible type}}
   bc = sc + bc2; // expected-error {{incompatible type}}
 
-  sc = sc + sc_scalar; // expected-error {{cannot convert}}
-  sc = sc + uc_scalar; // expected-error {{cannot convert}}
-  sc = sc_scalar + sc; // expected-error {{cannot convert}}
-  sc = uc_scalar + sc; // expected-error {{cannot convert}}
-  uc = uc + sc_scalar; // expected-error {{cannot convert}}
-  uc = uc + uc_scalar; // expected-error {{cannot convert}}
-  uc = sc_scalar + uc; // expected-error {{cannot convert}}
-  uc = uc_scalar + uc; // expected-error {{cannot convert}}
+  sc = sc + sc_scalar;
+  sc = sc + uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  sc = sc_scalar + sc;
+  sc = uc_scalar + sc; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc = uc + sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc + uc_scalar;
+  uc = sc_scalar + uc; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc_scalar + uc;
 
   ss = ss + ss2;
   us = us + us2;
@@ -368,10 +368,10 @@
   sc += sl2; // expected-error {{cannot convert}}
   sc += fd2; // expected-error {{cannot convert}}
 
-  sc += sc_scalar; // expected-error {{cannot convert}}
-  sc += uc_scalar; // expected-error {{cannot convert}}
-  uc += sc_scalar; // expected-error {{cannot convert}}
-  uc += uc_scalar; // expected-error {{cannot convert}}
+  sc += sc_scalar;
+  sc += uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc += sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc += uc_scalar;
 
   ss += ss2;
   us += us2;
Index: test/Sema/vector-ops.c
===
--- test/Sema/vector-ops.c
+++ test/Sema/vector-ops.c
@@ -13,7 +13,7 @@
   (void)(~v2fa); // expected-error{{invalid argument type 'v2f' (vector of 2 'float' values) to unary}}
 
   // Comparison operators
-  v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from 'int __attribute__((ext_vector_type(2)))' (vector of 2 'int' values)}}
+  v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int int' (vector of 2 'int' values)}}
   v2sa = (v2ua==v2sa);
   
   // Arrays
Index: test/Sema/vector-gcc-compat.c
===
--- /dev/null
+++ test/Sema/vector-gcc-compat.c
@@ -0,0 +1,335 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything
+
+// Test the compatibility of clang's vector extensions with gcc's vector
+// extensions for C. Notably &&, ||, ?: and ! are not available.
+typedef long long v2i64 __attribute__((vector_size(16)));
+typedef int v2i32 __attribute__((vector_size(8)));
+typedef short v2i16 __attribute__((vector_size(4)));
+typedef char v2i8 __attribute__((vector_size(2)));
+
+typedef unsigned long long v2u64 __attribute__((vector_size(16)));
+typedef unsigned int v2u32 __attribute__((vector_size(8)));
+typedef unsigned short v2u16 

[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-03-07 Thread Simon Dardis via Phabricator via cfe-commits
sdardis marked 3 inline comments as done.
sdardis added a comment.

Thanks for getting back to this. I've traced the appearance of the ext_vector 
type to a piece of code that only produces ext-vector types for comparisons. 
I'm presuming that's wrong when clang is producing vectors implicitly in the 
non-OpenCL case. I'll update the diff once I've changed that.




Comment at: test/Sema/vector-gcc-compat.c:61
+  //match.
+  v2i64_r = v2i64_a == 1; // expected-warning {{incompatible vector types 
assigning to 'v2i64' (vector of 2 'long long' values) from 'long 
__attribute__((ext_vector_type(2)))' (vector of 2 'long' values)}}
+  v2i64_r = v2i64_a != 1; // expected-warning {{incompatible vector types 
assigning to 'v2i64' (vector of 2 'long long' values) from 'long 
__attribute__((ext_vector_type(2)))' (vector of 2 'long' values)}}

bruno wrote:
> Can you double check where 'long __attribute__((ext_vector_type(2)))' comes 
> from?
> 
> We have regressed in the past year in the way ext-vector interacts with 
> non-ext-vectors, and I don't wanna make it worse until we actually have time 
> to fix that; there's a lot of code out there relying on bitcasts between 
> ext-vectors and non-ext-vectors to bridge between intrinsics headers and 
> ext-vector code.
Sema::CheckVectorCompareOperands calls Sema::GetSignedVectorType which only 
returns ext-vector types. I presume that is now incorrect if we're producing 
vectors from literal scalars in the non OpenCL case.


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-03-06 Thread Bruno Cardoso Lopes via Phabricator via cfe-commits
bruno added a comment.

Hey, really sorry for the delay here.




Comment at: lib/Sema/SemaExpr.cpp:8007
+static bool canConvertIntToOtherIntTy(Sema , ExprResult *Int,
+   QualType OtherIntTy) {
+  QualType IntTy = Int->get()->getType().getUnqualifiedType();

This doesn't look clang-formated. 



Comment at: lib/Sema/SemaExpr.cpp:8034
+NumBits > S.Context.getIntWidth(OtherIntTy))
+  return true;
+  } else {

Instead of the else here, you can:
   
  return (IntSigned != OtherIntSigned &&
  NumBits > S.Context.getIntWidth(OtherIntTy))
   }

   return (Order < 0);



Comment at: lib/Sema/SemaExpr.cpp:8092
+ExprResult *Vector) {
+  QualType ScalarTy = Scalar->get()->getType().getUnqualifiedType();
+  QualType VectorTy = Vector->get()->getType().getUnqualifiedType();

Can you please add an assertion to the beginning of this function to guarantee 
that the vector is never a ext-vector type? I wanna make sure we don't 
accidentally use this in the future for ext-vectors. 



Comment at: test/Sema/vector-gcc-compat.c:61
+  //match.
+  v2i64_r = v2i64_a == 1; // expected-warning {{incompatible vector types 
assigning to 'v2i64' (vector of 2 'long long' values) from 'long 
__attribute__((ext_vector_type(2)))' (vector of 2 'long' values)}}
+  v2i64_r = v2i64_a != 1; // expected-warning {{incompatible vector types 
assigning to 'v2i64' (vector of 2 'long long' values) from 'long 
__attribute__((ext_vector_type(2)))' (vector of 2 'long' values)}}

Can you double check where 'long __attribute__((ext_vector_type(2)))' comes 
from?

We have regressed in the past year in the way ext-vector interacts with 
non-ext-vectors, and I don't wanna make it worse until we actually have time to 
fix that; there's a lot of code out there relying on bitcasts between 
ext-vectors and non-ext-vectors to bridge between intrinsics headers and 
ext-vector code.


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-01-27 Thread Simon Dardis via Phabricator via cfe-commits
sdardis added a comment.

Ping.


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2017-01-05 Thread Simon Dardis via Phabricator via cfe-commits
sdardis added a comment.

Ping.


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2016-12-16 Thread Simon Dardis via Phabricator via cfe-commits
sdardis added inline comments.



Comment at: lib/Sema/SemaExpr.cpp:8051
+  if (!LHSVecType) {
+assert(RHSVecType && "RHSVecType is not a vector!");
 if (!tryVectorConvertAndSplat(*this, (IsCompAssign ? nullptr : ),

bruno wrote:
> `tryVectorConvertAndSplat` does more than plain scalar splat; it supports a 
> more general type of CK_IntegralCast, see the comment on one of your changes 
> to the tests below.
> 
> I suggest that instead of reusing this function, you should create another 
> one that only handles the cases we actually want to support for non-ext 
> vectors (i.e. for GCC compat). 
(ignore this, phabricator's web interface is acting up)



Comment at: lib/Sema/SemaExpr.cpp:8267
+  }
+
   // Otherwise, use the generic diagnostic.

bruno wrote:
> sdardis wrote:
> > bruno wrote:
> > > This change seems orthogonal to this patch. Can you make it a separated 
> > > patch with the changes from test/Sema/vector-cast.c?
> > This change is a necessary part of this patch and it can't be split out in 
> > sensible fashion.
> > 
> > For example, line 329 of test/Sema/zvector.c adds a scalar signed character 
> > to a vector of signed characters. With just this change we would report 
> > "cannot convert between scalar type 'signed char' and vector type '__vector 
> > signed char' (vector of 16 'signed char' values) as implicit conversion 
> > would cause truncation".
> > 
> > This is heavily misleading for C and C++ code as we don't perform implicit 
> > conversions and signed char could be implicitly converted to a vector of 
> > signed char without the loss of precision.
> > 
> > To make this diagnostic precise without performing implicit conversions 
> > requires determining cases where implicit conversion would cause truncation 
> > and reporting that failure reason, or defaulting to the generic diagnostic.
> > 
> > Keeping this change as part of this patch is cleaner and simpler as it 
> > covers both implicit conversions and more precise diagnostics.
> Can you double check whether we should support these GCC semantics for 
> getLangOpts().ZVector? If not, then this should be introduced in a separate 
> patch/commit.
See my comment above.



Comment at: lib/Sema/SemaExpr.cpp:8171
+return LHSType;
+}
   }

bruno wrote:
> It's not clear to me whether clang should support the GCC semantics when in 
> `getLangOpts().AltiVec || getLangOpts().ZVector`, do you?
> 
> You can remove the curly braces for the `if` and `else` here.
We should, GCC performs scalar to vector conversions regardless of what cpu 
features are available. If the target machine doesn't have vector support, GCC 
silently scalarizes the operation.

https://gcc.gnu.org/onlinedocs/gcc-6.2.0/gcc/Vector-Extensions.html#Vector-Extensions


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2016-12-16 Thread Simon Dardis via Phabricator via cfe-commits
sdardis updated this revision to Diff 81755.
sdardis marked an inline comment as done.
sdardis added a comment.

Addressed review comments, fixed assertion issue with expressions like scalar 
-= vector.


https://reviews.llvm.org/D25866

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaExpr.cpp
  test/Sema/vector-cast.c
  test/Sema/vector-gcc-compat.c
  test/Sema/zvector.c
  test/SemaCXX/vector-no-lax.cpp

Index: test/SemaCXX/vector-no-lax.cpp
===
--- test/SemaCXX/vector-no-lax.cpp
+++ test/SemaCXX/vector-no-lax.cpp
@@ -4,6 +4,6 @@
 
 vSInt32 foo (vUInt32 a) {
   vSInt32 b = { 0, 0, 0, 0 };
-  b += a; // expected-error{{cannot convert between vector values}}
+  b += a; // expected-error{{cannot convert between vector type 'vUInt32' (vector of 4 'unsigned int' values) and vector type 'vSInt32' (vector of 4 'int' values) as implicit conversion would cause truncation}}
   return b;
 }
Index: test/Sema/zvector.c
===
--- test/Sema/zvector.c
+++ test/Sema/zvector.c
@@ -326,14 +326,14 @@
   bc = bc + sc2; // expected-error {{incompatible type}}
   bc = sc + bc2; // expected-error {{incompatible type}}
 
-  sc = sc + sc_scalar; // expected-error {{cannot convert}}
-  sc = sc + uc_scalar; // expected-error {{cannot convert}}
-  sc = sc_scalar + sc; // expected-error {{cannot convert}}
-  sc = uc_scalar + sc; // expected-error {{cannot convert}}
-  uc = uc + sc_scalar; // expected-error {{cannot convert}}
-  uc = uc + uc_scalar; // expected-error {{cannot convert}}
-  uc = sc_scalar + uc; // expected-error {{cannot convert}}
-  uc = uc_scalar + uc; // expected-error {{cannot convert}}
+  sc = sc + sc_scalar;
+  sc = sc + uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  sc = sc_scalar + sc;
+  sc = uc_scalar + sc; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc = uc + sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc + uc_scalar;
+  uc = sc_scalar + uc; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc_scalar + uc;
 
   ss = ss + ss2;
   us = us + us2;
@@ -368,10 +368,10 @@
   sc += sl2; // expected-error {{cannot convert}}
   sc += fd2; // expected-error {{cannot convert}}
 
-  sc += sc_scalar; // expected-error {{cannot convert}}
-  sc += uc_scalar; // expected-error {{cannot convert}}
-  uc += sc_scalar; // expected-error {{cannot convert}}
-  uc += uc_scalar; // expected-error {{cannot convert}}
+  sc += sc_scalar;
+  sc += uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc += sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc += uc_scalar;
 
   ss += ss2;
   us += us2;
Index: test/Sema/vector-gcc-compat.c
===
--- /dev/null
+++ test/Sema/vector-gcc-compat.c
@@ -0,0 +1,304 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything
+typedef long long v2i64 __attribute__((vector_size(16)));
+typedef int v2i32 __attribute__((vector_size(8)));
+typedef short v2i16 __attribute__((vector_size(4)));
+typedef char v2i8 __attribute__((vector_size(2)));
+
+typedef unsigned long long v2u64 __attribute__((vector_size(16)));
+typedef unsigned int v2u32 __attribute__((vector_size(8)));
+typedef unsigned short v2u16 __attribute__((vector_size(4)));
+typedef unsigned char v2u8 __attribute__((vector_size(2)));
+
+typedef float v4f32 __attribute__((vector_size(16)));
+typedef double v4f64 __attribute__((vector_size(32)));
+
+void arithmeticTest(void);
+void logicTest(void);
+void comparisonTest(void);
+void floatTestSignedType(char a, short b, int c, long long d);
+void floatTestUnsignedType(unsigned char a, unsigned short b, unsigned int c,
+   unsigned long long d);
+void floatTestConstant(void);
+void intTestType(char a, short b, int c, long long d);
+void intTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d);
+void uintTestType(char a, short b, int c, long long d);
+void uintTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+  unsigned long long d);
+void uintTestConstant(v2u64 v2u64_a, v2u32 v2u32_a, v2u16 

[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2016-11-28 Thread Bruno Cardoso Lopes via Phabricator via cfe-commits
bruno added inline comments.



Comment at: lib/Sema/SemaExpr.cpp:8064
+  ScalarCast = CK_FloatingCast;
+} else if (ScalarTy->isIntegralType(S.Context)) {
+  // Determine if the integer constant can be expressed as a floating point

sdardis wrote:
> bruno wrote:
> > I don't see why it's necessary to check for all specific cases where the 
> > scalar is a constant. For all the others scenarios it should be enough to 
> > get the right answer via `getIntegerTypeOrder` or `getFloatTypeOrder`. For 
> > this is specific condition, the `else` part for the `CstScalar` below 
> > should also handle the constant case, right? 
> > 
> > 
> If we have a scalar constant, it is necessary to examine it's actual value to 
> see if it can be casted without truncation. The scalar constant's type is 
> somewhat irrelevant. Consider:
> 
>v4f32 f(v4f32 a) {
>  return a + (double)1.0;
>}
> 
> In this case examining the order only works if the vector's order is greater 
> than or equal to the scalar constant's order. Instead, if we ask whether the 
> scalar constant can be represented as a constant scalar of the vector's 
> element type, then we know if we can convert without the loss of precision.
> 
> For integers, the case is a little more contrived due to native integer 
> width, but the question is the same. Can a scalar constant X be represented 
> as a given floating point type. Consider:
> 
>v4f32 f(v4f32 a) {
>  return a + (signed int)1;
> }
> 
> This would rejected for platforms where a signed integer's width is greater 
> than the precision of float if we examined it based purely on types and their 
> sizes. Instead, if we convert the integer to the float point's type with 
> APFloat and convert back to see if we have the same value, we can determine 
> if the scalar constant can be safely converted without the loss of precision.
> 
> I based the logic examining the value of the constant scalar based on GCC's 
> behaviour, which implicitly converts scalars regardless of their type if they 
> can be represented in the same type of the vector's element type without the 
> loss of precision. If the scalar cannot be evaluated to a constant at compile 
> time, then the size in bits for the scalar's type determines if it can be 
> converted safely.
Right. Can you split the scalarTy <-> vectorEltTy checking logic into separate 
functions; one for cst-scalar-int-to-vec-elt-int and another for 
scalar-int-to-vec-elt-float? 



Comment at: lib/Sema/SemaExpr.cpp:8267
+  }
+
   // Otherwise, use the generic diagnostic.

sdardis wrote:
> bruno wrote:
> > This change seems orthogonal to this patch. Can you make it a separated 
> > patch with the changes from test/Sema/vector-cast.c?
> This change is a necessary part of this patch and it can't be split out in 
> sensible fashion.
> 
> For example, line 329 of test/Sema/zvector.c adds a scalar signed character 
> to a vector of signed characters. With just this change we would report 
> "cannot convert between scalar type 'signed char' and vector type '__vector 
> signed char' (vector of 16 'signed char' values) as implicit conversion would 
> cause truncation".
> 
> This is heavily misleading for C and C++ code as we don't perform implicit 
> conversions and signed char could be implicitly converted to a vector of 
> signed char without the loss of precision.
> 
> To make this diagnostic precise without performing implicit conversions 
> requires determining cases where implicit conversion would cause truncation 
> and reporting that failure reason, or defaulting to the generic diagnostic.
> 
> Keeping this change as part of this patch is cleaner and simpler as it covers 
> both implicit conversions and more precise diagnostics.
Can you double check whether we should support these GCC semantics for 
getLangOpts().ZVector? If not, then this should be introduced in a separate 
patch/commit.



Comment at: lib/Sema/SemaExpr.cpp:8020
+  if (Order < 0)
+return true;
+}

Please also early return `!CstScalar && Order < 0` like you did below.



Comment at: lib/Sema/SemaExpr.cpp:8064
+ !ScalarTy->hasSignedIntegerRepresentation());
+bool ignored = false;
+Float.convertToInteger(

`ignored` => `Ignored` 



Comment at: lib/Sema/SemaExpr.cpp:8171
+return LHSType;
+}
   }

It's not clear to me whether clang should support the GCC semantics when in 
`getLangOpts().AltiVec || getLangOpts().ZVector`, do you?

You can remove the curly braces for the `if` and `else` here.



Comment at: lib/Sema/SemaExpr.cpp:8182
+return RHSType;
+}
   }

Also remove braces here.


https://reviews.llvm.org/D25866



___
cfe-commits mailing list

[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2016-11-18 Thread Simon Dardis via cfe-commits
sdardis updated this revision to Diff 78531.
sdardis marked 4 inline comments as done.
sdardis added a comment.

Addressed review comments.


https://reviews.llvm.org/D25866

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaExpr.cpp
  test/Sema/vector-cast.c
  test/Sema/vector-gcc-compat.c
  test/Sema/zvector.c
  test/SemaCXX/vector-no-lax.cpp

Index: test/SemaCXX/vector-no-lax.cpp
===
--- test/SemaCXX/vector-no-lax.cpp
+++ test/SemaCXX/vector-no-lax.cpp
@@ -4,6 +4,6 @@
 
 vSInt32 foo (vUInt32 a) {
   vSInt32 b = { 0, 0, 0, 0 };
-  b += a; // expected-error{{cannot convert between vector values}}
+  b += a; // expected-error{{cannot convert between vector type 'vUInt32' (vector of 4 'unsigned int' values) and vector type 'vSInt32' (vector of 4 'int' values) as implicit conversion would cause truncation}}
   return b;
 }
Index: test/Sema/zvector.c
===
--- test/Sema/zvector.c
+++ test/Sema/zvector.c
@@ -326,14 +326,14 @@
   bc = bc + sc2; // expected-error {{incompatible type}}
   bc = sc + bc2; // expected-error {{incompatible type}}
 
-  sc = sc + sc_scalar; // expected-error {{cannot convert}}
-  sc = sc + uc_scalar; // expected-error {{cannot convert}}
-  sc = sc_scalar + sc; // expected-error {{cannot convert}}
-  sc = uc_scalar + sc; // expected-error {{cannot convert}}
-  uc = uc + sc_scalar; // expected-error {{cannot convert}}
-  uc = uc + uc_scalar; // expected-error {{cannot convert}}
-  uc = sc_scalar + uc; // expected-error {{cannot convert}}
-  uc = uc_scalar + uc; // expected-error {{cannot convert}}
+  sc = sc + sc_scalar;
+  sc = sc + uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  sc = sc_scalar + sc;
+  sc = uc_scalar + sc; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc = uc + sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc + uc_scalar;
+  uc = sc_scalar + uc; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc_scalar + uc;
 
   ss = ss + ss2;
   us = us + us2;
@@ -368,10 +368,10 @@
   sc += sl2; // expected-error {{cannot convert}}
   sc += fd2; // expected-error {{cannot convert}}
 
-  sc += sc_scalar; // expected-error {{cannot convert}}
-  sc += uc_scalar; // expected-error {{cannot convert}}
-  uc += sc_scalar; // expected-error {{cannot convert}}
-  uc += uc_scalar; // expected-error {{cannot convert}}
+  sc += sc_scalar;
+  sc += uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc += sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc += uc_scalar;
 
   ss += ss2;
   us += us2;
Index: test/Sema/vector-gcc-compat.c
===
--- /dev/null
+++ test/Sema/vector-gcc-compat.c
@@ -0,0 +1,304 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything
+typedef long long v2i64 __attribute__((vector_size(16)));
+typedef int v2i32 __attribute__((vector_size(8)));
+typedef short v2i16 __attribute__((vector_size(4)));
+typedef char v2i8 __attribute__((vector_size(2)));
+
+typedef unsigned long long v2u64 __attribute__((vector_size(16)));
+typedef unsigned int v2u32 __attribute__((vector_size(8)));
+typedef unsigned short v2u16 __attribute__((vector_size(4)));
+typedef unsigned char v2u8 __attribute__((vector_size(2)));
+
+typedef float v4f32 __attribute__((vector_size(16)));
+typedef double v4f64 __attribute__((vector_size(32)));
+
+void arithmeticTest(void);
+void logicTest(void);
+void comparisonTest(void);
+void floatTestSignedType(char a, short b, int c, long long d);
+void floatTestUnsignedType(unsigned char a, unsigned short b, unsigned int c,
+   unsigned long long d);
+void floatTestConstant(void);
+void intTestType(char a, short b, int c, long long d);
+void intTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d);
+void uintTestType(char a, short b, int c, long long d);
+void uintTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+  unsigned long long d);
+void uintTestConstant(v2u64 v2u64_a, v2u32 v2u32_a, v2u16 v2u16_a, v2u8 v2u8_a);
+void intTestConstant(v2i64 v2i64_a, v2i32 

[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2016-11-18 Thread Simon Dardis via cfe-commits
sdardis added inline comments.



Comment at: lib/Sema/SemaExpr.cpp:8064
+  ScalarCast = CK_FloatingCast;
+} else if (ScalarTy->isIntegralType(S.Context)) {
+  // Determine if the integer constant can be expressed as a floating point

bruno wrote:
> I don't see why it's necessary to check for all specific cases where the 
> scalar is a constant. For all the others scenarios it should be enough to get 
> the right answer via `getIntegerTypeOrder` or `getFloatTypeOrder`. For this 
> is specific condition, the `else` part for the `CstScalar` below should also 
> handle the constant case, right? 
> 
> 
If we have a scalar constant, it is necessary to examine it's actual value to 
see if it can be casted without truncation. The scalar constant's type is 
somewhat irrelevant. Consider:

   v4f32 f(v4f32 a) {
 return a + (double)1.0;
   }

In this case examining the order only works if the vector's order is greater 
than or equal to the scalar constant's order. Instead, if we ask whether the 
scalar constant can be represented as a constant scalar of the vector's element 
type, then we know if we can convert without the loss of precision.

For integers, the case is a little more contrived due to native integer width, 
but the question is the same. Can a scalar constant X be represented as a given 
floating point type. Consider:

   v4f32 f(v4f32 a) {
 return a + (signed int)1;
}

This would rejected for platforms where a signed integer's width is greater 
than the precision of float if we examined it based purely on types and their 
sizes. Instead, if we convert the integer to the float point's type with 
APFloat and convert back to see if we have the same value, we can determine if 
the scalar constant can be safely converted without the loss of precision.

I based the logic examining the value of the constant scalar based on GCC's 
behaviour, which implicitly converts scalars regardless of their type if they 
can be represented in the same type of the vector's element type without the 
loss of precision. If the scalar cannot be evaluated to a constant at compile 
time, then the size in bits for the scalar's type determines if it can be 
converted safely.



Comment at: lib/Sema/SemaExpr.cpp:8267
+  }
+
   // Otherwise, use the generic diagnostic.

bruno wrote:
> This change seems orthogonal to this patch. Can you make it a separated patch 
> with the changes from test/Sema/vector-cast.c?
This change is a necessary part of this patch and it can't be split out in 
sensible fashion.

For example, line 329 of test/Sema/zvector.c adds a scalar signed character to 
a vector of signed characters. With just this change we would report "cannot 
convert between scalar type 'signed char' and vector type '__vector signed 
char' (vector of 16 'signed char' values) as implicit conversion would cause 
truncation".

This is heavily misleading for C and C++ code as we don't perform implicit 
conversions and signed char could be implicitly converted to a vector of signed 
char without the loss of precision.

To make this diagnostic precise without performing implicit conversions 
requires determining cases where implicit conversion would cause truncation and 
reporting that failure reason, or defaulting to the generic diagnostic.

Keeping this change as part of this patch is cleaner and simpler as it covers 
both implicit conversions and more precise diagnostics.


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2016-11-17 Thread Bruno Cardoso Lopes via cfe-commits
bruno added inline comments.



Comment at: lib/Sema/SemaExpr.cpp:7978
+/// without causing truncation of Scalar.
+
+static bool tryGCCVectorConvertAndSpalt(Sema , ExprResult *Scalar,

Remove this empty line.



Comment at: lib/Sema/SemaExpr.cpp:7991
+  (!ScalarTy->isIntegralType(S.Context) &&
+   !ScalarTy->isRealFloatingType()))
+return true;

This can be simplified by checking isArithmeticType() for each instead.



Comment at: lib/Sema/SemaExpr.cpp:8005
+// type and then perform the rest of the checks here.
+if (!ScalarTy->isIntegralType(S.Context))
+  return true;

You already checked this condition in the `if` above, this will never trigger.



Comment at: lib/Sema/SemaExpr.cpp:8043
+  } else if (VectorEltTy->isRealFloatingType()) {
+if (ScalarTy->isRealFloatingType() && VectorEltTy != ScalarTy) {
+

I don't see how `VectorEltTy != ScalarTy` is possible here.



Comment at: lib/Sema/SemaExpr.cpp:8064
+  ScalarCast = CK_FloatingCast;
+} else if (ScalarTy->isIntegralType(S.Context)) {
+  // Determine if the integer constant can be expressed as a floating point

I don't see why it's necessary to check for all specific cases where the scalar 
is a constant. For all the others scenarios it should be enough to get the 
right answer via `getIntegerTypeOrder` or `getFloatTypeOrder`. For this is 
specific condition, the `else` part for the `CstScalar` below should also 
handle the constant case, right? 





Comment at: lib/Sema/SemaExpr.cpp:8267
+  }
+
   // Otherwise, use the generic diagnostic.

This change seems orthogonal to this patch. Can you make it a separated patch 
with the changes from test/Sema/vector-cast.c?



Comment at: test/Sema/vector-gcc-compat.c:2
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything
+
+typedef long long v2i64 __attribute__((vector_size(16)));

These are really nice tests. Some cosmetic cleanups: can you run it through 
clang-format and also remove (a) newlines between comments and codes, (b) 
places with double newlines?


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2016-11-08 Thread Simon Dardis via cfe-commits
sdardis added a comment.

Ping.


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2016-10-31 Thread Simon Dardis via cfe-commits
sdardis updated the summary for this revision.
sdardis updated this revision to Diff 76385.
sdardis added a comment.

Split out a variant of tryVectorConvertAndSplat called 
tryGCCVectorConvertAndSplat. This variant checks the types more strictly than 
tryVectorConvertAndSplat and handles implicit conversion of constants which can 
be safely demoted to a smaller type.
Added more testing to vector-gcc-compat.c


https://reviews.llvm.org/D25866

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaExpr.cpp
  test/Sema/vector-cast.c
  test/Sema/vector-gcc-compat.c
  test/Sema/zvector.c
  test/SemaCXX/vector-no-lax.cpp

Index: test/SemaCXX/vector-no-lax.cpp
===
--- test/SemaCXX/vector-no-lax.cpp
+++ test/SemaCXX/vector-no-lax.cpp
@@ -4,6 +4,6 @@
 
 vSInt32 foo (vUInt32 a) {
   vSInt32 b = { 0, 0, 0, 0 };
-  b += a; // expected-error{{cannot convert between vector values}}
+  b += a; // expected-error{{cannot convert between vector type 'vUInt32' (vector of 4 'unsigned int' values) and vector type 'vSInt32' (vector of 4 'int' values) as implicit conversion would cause truncation}}
   return b;
 }
Index: test/Sema/zvector.c
===
--- test/Sema/zvector.c
+++ test/Sema/zvector.c
@@ -326,14 +326,14 @@
   bc = bc + sc2; // expected-error {{incompatible type}}
   bc = sc + bc2; // expected-error {{incompatible type}}
 
-  sc = sc + sc_scalar; // expected-error {{cannot convert}}
-  sc = sc + uc_scalar; // expected-error {{cannot convert}}
-  sc = sc_scalar + sc; // expected-error {{cannot convert}}
-  sc = uc_scalar + sc; // expected-error {{cannot convert}}
-  uc = uc + sc_scalar; // expected-error {{cannot convert}}
-  uc = uc + uc_scalar; // expected-error {{cannot convert}}
-  uc = sc_scalar + uc; // expected-error {{cannot convert}}
-  uc = uc_scalar + uc; // expected-error {{cannot convert}}
+  sc = sc + sc_scalar;
+  sc = sc + uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  sc = sc_scalar + sc;
+  sc = uc_scalar + sc; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc = uc + sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc + uc_scalar;
+  uc = sc_scalar + uc; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc_scalar + uc;
 
   ss = ss + ss2;
   us = us + us2;
@@ -368,10 +368,10 @@
   sc += sl2; // expected-error {{cannot convert}}
   sc += fd2; // expected-error {{cannot convert}}
 
-  sc += sc_scalar; // expected-error {{cannot convert}}
-  sc += uc_scalar; // expected-error {{cannot convert}}
-  uc += sc_scalar; // expected-error {{cannot convert}}
-  uc += uc_scalar; // expected-error {{cannot convert}}
+  sc += sc_scalar;
+  sc += uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+  uc += sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc += uc_scalar;
 
   ss += ss2;
   us += us2;
Index: test/Sema/vector-gcc-compat.c
===
--- /dev/null
+++ test/Sema/vector-gcc-compat.c
@@ -0,0 +1,312 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything
+
+typedef long long v2i64 __attribute__((vector_size(16)));
+typedef int v2i32 __attribute__((vector_size(8)));
+typedef short v2i16 __attribute__((vector_size(4)));
+typedef char v2i8 __attribute__((vector_size(2)));
+
+typedef unsigned long long v2u64 __attribute__((vector_size(16)));
+typedef unsigned int v2u32 __attribute__((vector_size(8)));
+typedef unsigned short v2u16 __attribute__((vector_size(4)));
+typedef unsigned char v2u8 __attribute__((vector_size(2)));
+
+typedef float v4f32 __attribute__((vector_size(16)));
+typedef double v4f64 __attribute__((vector_size(32)));
+
+void arithmeticTest (void);
+void logicTest (void);
+void comparisonTest (void);
+void floatTestSignedType (char a, short b, int c, long long d);
+void floatTestUnsignedType (unsigned char a, unsigned short b, unsigned int c, unsigned long long d);
+void floatTestConstant (void);
+void intTestType (char a, short b, int c, long long d);
+void intTestTypeUnsigned (unsigned char a, unsigned short b, unsigned int c, unsigned long long d);
+void uintTestType (char a, short b, int c, long long d);
+void 

[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2016-10-25 Thread Bruno Cardoso Lopes via cfe-commits
bruno added a comment.

Hi,

Nice, thanks for working on this!




Comment at: lib/Sema/SemaExpr.cpp:8051
+  if (!LHSVecType) {
+assert(RHSVecType && "RHSVecType is not a vector!");
 if (!tryVectorConvertAndSplat(*this, (IsCompAssign ? nullptr : ),

`tryVectorConvertAndSplat` does more than plain scalar splat; it supports a 
more general type of CK_IntegralCast, see the comment on one of your changes to 
the tests below.

I suggest that instead of reusing this function, you should create another one 
that only handles the cases we actually want to support for non-ext vectors 
(i.e. for GCC compat). 



Comment at: test/Sema/vector-cast.c:57
+  // FIXME: This lacks a diagnostic: should complain that 'double' to vector 
'float2' involves truncation
+  f2 += d;
+  d += f2; // expected-error {{assigning to 'double' from incompatible type 
'float2' (vector of 2 'float' values)}}

This is not right. The fact that we don't have the appropriate diagnostics here 
doesn't mean we should accept this. For instance, this is what we get with GCC:

error: conversion of scalar 'double' to vector 'float2 {aka __vector(2) float}' 
involves truncation



Comment at: test/Sema/vector-scalar-implict-conv.c:2
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything
+
+typedef long long v2i64 __attribute__((vector_size(16)));

Can you rename this to vector-gcc-compat.c? It would also be nice to split 
functionality being tested within their own function, e.g.: arithmetic, logic, 
vector comparisons.


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2016-10-25 Thread Simon Dardis via cfe-commits
sdardis updated this revision to Diff 75708.
sdardis marked an inline comment as done.
sdardis added a comment.

Extra testing for cases where the operand on the left of an operation is a 
vector.
Removed two spurious checks for vector types.


https://reviews.llvm.org/D25866

Files:
  lib/Sema/SemaExpr.cpp
  test/Sema/vector-cast.c
  test/Sema/vector-scalar-implict-conv.c
  test/Sema/zvector.c

Index: test/Sema/zvector.c
===
--- test/Sema/zvector.c
+++ test/Sema/zvector.c
@@ -326,14 +326,14 @@
   bc = bc + sc2; // expected-error {{incompatible type}}
   bc = sc + bc2; // expected-error {{incompatible type}}
 
-  sc = sc + sc_scalar; // expected-error {{cannot convert}}
-  sc = sc + uc_scalar; // expected-error {{cannot convert}}
-  sc = sc_scalar + sc; // expected-error {{cannot convert}}
-  sc = uc_scalar + sc; // expected-error {{cannot convert}}
-  uc = uc + sc_scalar; // expected-error {{cannot convert}}
-  uc = uc + uc_scalar; // expected-error {{cannot convert}}
-  uc = sc_scalar + uc; // expected-error {{cannot convert}}
-  uc = uc_scalar + uc; // expected-error {{cannot convert}}
+  sc = sc + sc_scalar;
+  sc = sc + uc_scalar; // expected-error {{implicit conversion changes signedness: 'unsigned char' to '__vector signed char' (vector of 16 'signed char' values)}}
+  sc = sc_scalar + sc;
+  sc = uc_scalar + sc; // expected-error {{implicit conversion changes signedness: 'unsigned char' to '__vector signed char' (vector of 16 'signed char' values)}}
+  uc = uc + sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc + uc_scalar;
+  uc = sc_scalar + uc; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc_scalar + uc;
 
   ss = ss + ss2;
   us = us + us2;
@@ -368,10 +368,10 @@
   sc += sl2; // expected-error {{cannot convert}}
   sc += fd2; // expected-error {{cannot convert}}
 
-  sc += sc_scalar; // expected-error {{cannot convert}}
-  sc += uc_scalar; // expected-error {{cannot convert}}
-  uc += sc_scalar; // expected-error {{cannot convert}}
-  uc += uc_scalar; // expected-error {{cannot convert}}
+  sc += sc_scalar;
+  sc += uc_scalar; // expected-error {{implicit conversion changes signedness: 'unsigned char' to '__vector signed char' (vector of 16 'signed char' values)}}
+  uc += sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc += uc_scalar;
 
   ss += ss2;
   us += us2;
Index: test/Sema/vector-scalar-implict-conv.c
===
--- /dev/null
+++ test/Sema/vector-scalar-implict-conv.c
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything
+
+typedef long long v2i64 __attribute__((vector_size(16)));
+typedef long long v2i64 __attribute__((vector_size(16)));
+
+typedef int v2i32 __attribute__((vector_size(8)));
+typedef int v2i32 __attribute__((vector_size(8)));
+
+typedef unsigned long long v2u64 __attribute__((vector_size(16)));
+typedef unsigned long long v2u64 __attribute__((vector_size(16)));
+
+typedef float v4f32 __attribute__((vector_size(16)));
+typedef double v4f64 __attribute__((vector_size(32)));
+
+void test (void);
+
+void test (void){
+
+  v2i64 v2i64_a = (v2i64) {0, 1};
+  v2i64 v2i64_r;
+
+  v2i32 v2i32_a = (v2i32) {0 , 1};
+
+  v2u64 v2u64_a = (v2u64) {0, 1};
+
+  v4f32 v4f32_a = (v4f32) {0.1f, 0.2f, 0.3f, 0.4f};
+
+  v4f64 v4f64_r = v4f32_a; // expected-error {{initializing 'v4f64' (vector of 4 'double' values) with an expression of incompatible type 'v4f32' (vector of 4 'float' values)}}
+
+  v4f64_r = v4f32_a;
+
+  // FIXME: this should warn about truncation.
+  v4f32_a = v4f64_r;
+
+  v2i64_r = v2i32_a; // expected-error {{assigning to 'v2i64' (vector of 2 'long long' values) from incompatible type 'v2i32' (vector of 2 'int' values)}}
+
+  v2i64_r = v2u64_a; // expected-warning {{incompatible vector types assigning to 'v2i64' (vector of 2 'long long' values) from 'v2u64' (vector of 2 'unsigned long long' values)}}
+
+  v2i64_r = v2i64_a + 1;
+  v2i64_r = v2i64_a - 1;
+  v2i64_r = v2i64_a * 1;
+  v2i64_r = v2i64_a / 1;
+  v2i64_r = v2i64_a % 1;
+
+  v2i64_r = 1 + v2i64_a;
+  v2i64_r = 1 - v2i64_a;
+  v2i64_r = 1 * v2i64_a;
+  v2i64_r = 1 / v2i64_a;
+  v2i64_r = 1 % v2i64_a;
+
+
+  v2i64_a += 1;
+  v2i64_a -= 1;
+  v2i64_a *= 1;
+  v2i64_a /= 1;
+  v2i64_a %= 1;
+
+  v2i64_r = v2i64_a == 1; // expected-warning {{incompatible vector types assigning to 'v2i64' (vector of 2 'long long' values) from 'long __attribute__((ext_vector_type(2)))' (vector of 2 'long' values)}}
+  v2i64_r = v2i64_a != 1; // expected-warning {{incompatible vector types assigning to 'v2i64' (vector of 2 'long long' values) from 'long 

[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2016-10-21 Thread Akira Hatanaka via cfe-commits
ahatanak added inline comments.



Comment at: lib/Sema/SemaExpr.cpp:8044
   // the vector element type and splat.
-  // FIXME: this should also work for regular vector types as supported in GCC.
-  if (!RHSVecType && isa(LHSVecType)) {
+  if (!RHSVecType && isa(LHSVecType)) {
 if (!tryVectorConvertAndSplat(*this, , RHSType,

ahatanak wrote:
> Is this the same as "!RHSVecType && LHSVecType" in this context?
Actually, LHS's type should be a vector here if RHS isn't a vector since 
CheckVectorOperands is called only when at least one operand is a vector.


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2016-10-21 Thread Akira Hatanaka via cfe-commits
ahatanak added inline comments.



Comment at: lib/Sema/SemaExpr.cpp:8044
   // the vector element type and splat.
-  // FIXME: this should also work for regular vector types as supported in GCC.
-  if (!RHSVecType && isa(LHSVecType)) {
+  if (!RHSVecType && isa(LHSVecType)) {
 if (!tryVectorConvertAndSplat(*this, , RHSType,

Is this the same as "!RHSVecType && LHSVecType" in this context?


https://reviews.llvm.org/D25866



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


[PATCH] D25866: [Sema] Support implicit scalar to vector conversions

2016-10-21 Thread Simon Dardis via cfe-commits
sdardis created this revision.
sdardis added subscribers: rnk, bruno, ahatanak, cfe-commits.
Herald added a reviewer: vkalintiris.

This patch teaches clang to perform implicit scalar to vector conversions
when one of the operands to a binary vector expression is a scalar like GCC.

The scalar is implicitly casted to the vector elements type and splatted to
produce a vector of the same type.


https://reviews.llvm.org/D25866

Files:
  lib/Sema/SemaExpr.cpp
  test/Sema/vector-cast.c
  test/Sema/vector-scalar-implict-conv.c
  test/Sema/zvector.c

Index: test/Sema/zvector.c
===
--- test/Sema/zvector.c
+++ test/Sema/zvector.c
@@ -326,14 +326,14 @@
   bc = bc + sc2; // expected-error {{incompatible type}}
   bc = sc + bc2; // expected-error {{incompatible type}}
 
-  sc = sc + sc_scalar; // expected-error {{cannot convert}}
-  sc = sc + uc_scalar; // expected-error {{cannot convert}}
-  sc = sc_scalar + sc; // expected-error {{cannot convert}}
-  sc = uc_scalar + sc; // expected-error {{cannot convert}}
-  uc = uc + sc_scalar; // expected-error {{cannot convert}}
-  uc = uc + uc_scalar; // expected-error {{cannot convert}}
-  uc = sc_scalar + uc; // expected-error {{cannot convert}}
-  uc = uc_scalar + uc; // expected-error {{cannot convert}}
+  sc = sc + sc_scalar;
+  sc = sc + uc_scalar; // expected-error {{implicit conversion changes signedness: 'unsigned char' to '__vector signed char' (vector of 16 'signed char' values)}}
+  sc = sc_scalar + sc;
+  sc = uc_scalar + sc; // expected-error {{implicit conversion changes signedness: 'unsigned char' to '__vector signed char' (vector of 16 'signed char' values)}}
+  uc = uc + sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc + uc_scalar;
+  uc = sc_scalar + uc; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc = uc_scalar + uc;
 
   ss = ss + ss2;
   us = us + us2;
@@ -368,10 +368,10 @@
   sc += sl2; // expected-error {{cannot convert}}
   sc += fd2; // expected-error {{cannot convert}}
 
-  sc += sc_scalar; // expected-error {{cannot convert}}
-  sc += uc_scalar; // expected-error {{cannot convert}}
-  uc += sc_scalar; // expected-error {{cannot convert}}
-  uc += uc_scalar; // expected-error {{cannot convert}}
+  sc += sc_scalar;
+  sc += uc_scalar; // expected-error {{implicit conversion changes signedness: 'unsigned char' to '__vector signed char' (vector of 16 'signed char' values)}}
+  uc += sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+  uc += uc_scalar;
 
   ss += ss2;
   us += us2;
Index: test/Sema/vector-scalar-implict-conv.c
===
--- /dev/null
+++ test/Sema/vector-scalar-implict-conv.c
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything
+
+typedef long long v2i64 __attribute__((vector_size(16)));
+typedef long long v2i64 __attribute__((vector_size(16)));
+
+typedef int v2i32 __attribute__((vector_size(8)));
+typedef int v2i32 __attribute__((vector_size(8)));
+
+typedef unsigned long long v2u64 __attribute__((vector_size(16)));
+typedef unsigned long long v2u64 __attribute__((vector_size(16)));
+
+typedef float v4f32 __attribute__((vector_size(16)));
+typedef double v4f64 __attribute__((vector_size(32)));
+
+void test (void);
+
+void test (void){
+
+  v2i64 v2i64_a = (v2i64) {0, 1};
+  v2i64 v2i64_r;
+
+  v2i32 v2i32_a = (v2i32) {0 , 1};
+
+  v2u64 v2u64_a = (v2u64) {0, 1};
+
+  v4f32 v4f32_a = (v4f32) {0.1f, 0.2f, 0.3f, 0.4f};
+
+  v4f64 v4f64_r = v4f32_a; // expected-error {{initializing 'v4f64' (vector of 4 'double' values) with an expression of incompatible type 'v4f32' (vector of 4 'float' values)}}
+
+  v4f64_r = v4f32_a;
+
+  // FIXME: this should warn about truncation.
+  v4f32_a = v4f64_r;
+
+  v2i64_r = v2i32_a; // expected-error {{assigning to 'v2i64' (vector of 2 'long long' values) from incompatible type 'v2i32' (vector of 2 'int' values)}}
+
+  v2i64_r = v2u64_a; // expected-warning {{incompatible vector types assigning to 'v2i64' (vector of 2 'long long' values) from 'v2u64' (vector of 2 'unsigned long long' values)}}
+
+  v2i64_r = v2i64_a + 1;
+  v2i64_r = v2i64_a - 1;
+  v2i64_r = v2i64_a * 1;
+  v2i64_r = v2i64_a / 1;
+  v2i64_r = v2i64_a % 1;
+
+  v2i64_a += 1;
+  v2i64_a -= 1;
+  v2i64_a *= 1;
+  v2i64_a /= 1;
+  v2i64_a %= 1;
+
+  v2i64_r = v2i64_a == 1; // expected-warning {{incompatible vector types assigning to 'v2i64' (vector of 2 'long long' values) from 'long __attribute__((ext_vector_type(2)))' (vector of 2 'long' values)}}
+  v2i64_r = v2i64_a != 1; // expected-warning {{incompatible vector types assigning to 'v2i64' (vector of 2 'long long' values) from 'long