<div dir="ltr">Then I'll take a look, and if it's not something trivial I'll revert it.</div><br><div class="gmail_quote"><div dir="ltr">On Mon, May 15, 2017 at 1:00 PM Simon Dardis <<a href="mailto:Simon.Dardis@imgtec.com">Simon.Dardis@imgtec.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Thanks, I'll try and look at this tomorrow.<br>
<br>
Simon<br>
<br>
<br>
<br>
From: Vitaly Buka [<a href="mailto:vitalybuka@google.com" target="_blank">vitalybuka@google.com</a>]<br>
<br>
Sent: 15 May 2017 20:57<br>
<br>
To: Simon Dardis; <a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<br>
Subject: Re: r302935 - [Sema] Support implicit scalar to vector conversions<br>
<br>
<br>
>From ubsan bot:<br>
<br>
<a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/4892/steps/check-clang%20ubsan/logs/stdio" rel="noreferrer" target="_blank">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/4892/steps/check-clang%20ubsan/logs/stdio</a><br>
<br>
llvm/tools/clang/lib/Sema/SemaExpr.cpp:8257:9: runtime error: load of value 4294967295, which is not a valid value for type 'clang::CastKind'<br>
#0 0x5bc3b88 in tryGCCVectorConvertAndSplat(clang::Sema&, clang::ActionResult<clang::Expr*, true>*, clang::ActionResult<clang::Expr*, true>*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Sema/SemaExpr.cpp:8257:9<br>
#1 0x5bbbea5 in clang::Sema::CheckVectorOperands(clang::ActionResult<clang::Expr*, true>&, clang::ActionResult<clang::Expr*, true>&, clang::SourceLocation, bool, bool, bool) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Sema/SemaExpr.cpp:8352:12<br>
#2 0x5bcc553 in clang::Sema::CheckVectorCompareOperands(clang::ActionResult<clang::Expr*, true>&, clang::ActionResult<clang::Expr*, true>&, clang::SourceLocation, bool) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Sema/SemaExpr.cpp:9990:20<br>
#3 0x5bc93a8 in clang::Sema::CheckCompareOperands(clang::ActionResult<clang::Expr*, true>&, clang::ActionResult<clang::Expr*, true>&, clang::SourceLocation, clang::BinaryOperatorKind, bool) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Sema/SemaExpr.cpp:9495:12<br>
<br>
<br>
<br>
On Fri, May 12, 2017 at 12:24 PM Simon Dardis via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br>
<br>
<br>
<br>
Author: sdardis<br>
<br>
Date: Fri May 12 14:11:06 2017<br>
<br>
New Revision: 302935<br>
<br>
<br>
<br>
URL:<br>
<a href="http://llvm.org/viewvc/llvm-project?rev=302935&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=302935&view=rev</a><br>
<br>
Log:<br>
<br>
[Sema] Support implicit scalar to vector conversions<br>
<br>
<br>
<br>
This patch teaches clang to perform implicit scalar to vector conversions<br>
<br>
when one of the operands of a binary vector expression is a scalar which<br>
<br>
can be converted to the element type of the vector without truncation<br>
<br>
following GCC's implementation.<br>
<br>
<br>
<br>
If the (constant) scalar is can be casted safely, it is implicitly casted to the<br>
<br>
vector elements type and splatted to produce a vector of the same type.<br>
<br>
<br>
<br>
Contributions from: Petar Jovanovic<br>
<br>
<br>
<br>
Reviewers: bruno, vkalintiris<br>
<br>
<br>
<br>
Differential Revision:<br>
<a href="https://reviews.llvm.org/D25866" rel="noreferrer" target="_blank">https://reviews.llvm.org/D25866</a><br>
<br>
<br>
<br>
<br>
<br>
Added:<br>
<br>
cfe/trunk/test/Sema/vector-gcc-compat.c<br>
<br>
cfe/trunk/test/Sema/vector-gcc-compat.cpp<br>
<br>
Modified:<br>
<br>
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
<br>
cfe/trunk/include/clang/Sema/Sema.h<br>
<br>
cfe/trunk/lib/Sema/SemaExpr.cpp<br>
<br>
cfe/trunk/lib/Sema/SemaExprCXX.cpp<br>
<br>
cfe/trunk/test/Sema/vector-cast.c<br>
<br>
cfe/trunk/test/Sema/vector-ops.c<br>
<br>
cfe/trunk/test/Sema/zvector.c<br>
<br>
cfe/trunk/test/SemaCXX/vector-no-lax.cpp<br>
<br>
<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
<br>
URL:<br>
<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=302935&r1=302934&r2=302935&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=302935&r1=302934&r2=302935&view=diff</a><br>
<br>
==============================================================================<br>
<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri May 12 14:11:06 2017<br>
<br>
@@ -2465,6 +2465,9 @@ def err_attribute_invalid_size : Error<<br>
<br>
"vector size not an integral multiple of component size">;<br>
<br>
def err_attribute_zero_size : Error<"zero vector size">;<br>
<br>
def err_attribute_size_too_large : Error<"vector size too large">;<br>
<br>
+def err_typecheck_vector_not_convertable_implict_truncation : Error<<br>
<br>
+ "cannot convert between %select{scalar|vector}0 type %1 and vector type"<br>
<br>
+ " %2 as implicit conversion would cause truncation">;<br>
<br>
def err_typecheck_vector_not_convertable : Error<<br>
<br>
"cannot convert between vector values of different size (%0 and %1)">;<br>
<br>
def err_typecheck_vector_not_convertable_non_scalar : Error<<br>
<br>
@@ -5779,6 +5782,9 @@ def err_objc_object_assignment : Error<<br>
<br>
"cannot assign to class object (%0 invalid)">;<br>
<br>
def err_typecheck_invalid_operands : Error<<br>
<br>
"invalid operands to binary expression (%0 and %1)">;<br>
<br>
+def err_typecheck_logical_vector_expr_gnu_cpp_restrict : Error<<br>
<br>
+ "logical expression with vector %select{type %1 and non-vector type %2|types"<br>
<br>
+ " %1 and %2}0 is only supported in C++">;<br>
<br>
def err_typecheck_sub_ptr_compatible : Error<<br>
<br>
"%diff{$ and $ are not pointers to compatible types|"<br>
<br>
"pointers to incompatible types}0,1">;<br>
<br>
<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
<br>
URL:<br>
<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=302935&r1=302934&r2=302935&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=302935&r1=302934&r2=302935&view=diff</a><br>
<br>
==============================================================================<br>
<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Fri May 12 14:11:06 2017<br>
<br>
@@ -9285,6 +9285,8 @@ public:<br>
<br>
/// type checking binary operators (subroutines of CreateBuiltinBinOp).<br>
<br>
QualType InvalidOperands(SourceLocation Loc, ExprResult &LHS,<br>
<br>
ExprResult &RHS);<br>
<br>
+ QualType InvalidLogicalVectorOperands(SourceLocation Loc, ExprResult &LHS,<br>
<br>
+ ExprResult &RHS);<br>
<br>
QualType CheckPointerToMemberOperands( // C++ 5.5<br>
<br>
ExprResult &LHS, ExprResult &RHS, ExprValueKind &VK,<br>
<br>
SourceLocation OpLoc, bool isIndirect);<br>
<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
<br>
URL:<br>
<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=302935&r1=302934&r2=302935&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=302935&r1=302934&r2=302935&view=diff</a><br>
<br>
==============================================================================<br>
<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri May 12 14:11:06 2017<br>
<br>
@@ -8031,6 +8031,33 @@ QualType Sema::InvalidOperands(SourceLoc<br>
<br>
return QualType();<br>
<br>
}<br>
<br>
<br>
<br>
+// Diagnose cases where a scalar was implicitly converted to a vector and<br>
<br>
+// diagnose the underlying types. Otherwise, diagnose the error<br>
<br>
+// as invalid vector logical operands for non-C++ cases.<br>
<br>
+QualType Sema::InvalidLogicalVectorOperands(SourceLocation Loc, ExprResult &LHS,<br>
<br>
+ ExprResult &RHS) {<br>
<br>
+ QualType LHSType = LHS.get()->IgnoreImpCasts()->getType();<br>
<br>
+ QualType RHSType = RHS.get()->IgnoreImpCasts()->getType();<br>
<br>
+<br>
<br>
+ bool LHSNatVec = LHSType->isVectorType();<br>
<br>
+ bool RHSNatVec = RHSType->isVectorType();<br>
<br>
+<br>
<br>
+ if (!(LHSNatVec && RHSNatVec)) {<br>
<br>
+ Expr *Vector = LHSNatVec ? LHS.get() : RHS.get();<br>
<br>
+ Expr *NonVector = !LHSNatVec ? LHS.get() : RHS.get();<br>
<br>
+ Diag(Loc, diag::err_typecheck_logical_vector_expr_gnu_cpp_restrict)<br>
<br>
+ << 0 << Vector->getType() << NonVector->IgnoreImpCasts()->getType()<br>
<br>
+ << Vector->getSourceRange();<br>
<br>
+ return QualType();<br>
<br>
+ }<br>
<br>
+<br>
<br>
+ Diag(Loc, diag::err_typecheck_logical_vector_expr_gnu_cpp_restrict)<br>
<br>
+ << 1 << LHSType << RHSType << LHS.get()->getSourceRange()<br>
<br>
+ << RHS.get()->getSourceRange();<br>
<br>
+<br>
<br>
+ return QualType();<br>
<br>
+}<br>
<br>
+<br>
<br>
/// Try to convert a value of non-vector type to a vector type by converting<br>
<br>
/// the type to the element type of the vector and then performing a splat.<br>
<br>
/// If the language is OpenCL, we only use conversions that promote scalar<br>
<br>
@@ -8078,6 +8105,162 @@ static bool tryVectorConvertAndSplat(Sem<br>
<br>
return false;<br>
<br>
}<br>
<br>
<br>
<br>
+/// Test if a (constant) integer Int can be casted to another integer type<br>
<br>
+/// IntTy without losing precision.<br>
<br>
+static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int,<br>
<br>
+ QualType OtherIntTy) {<br>
<br>
+ QualType IntTy = Int->get()->getType().getUnqualifiedType();<br>
<br>
+<br>
<br>
+ // Reject cases where the value of the Int is unknown as that would<br>
<br>
+ // possibly cause truncation, but accept cases where the scalar can be<br>
<br>
+ // demoted without loss of precision.<br>
<br>
+ llvm::APSInt Result;<br>
<br>
+ bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context);<br>
<br>
+ int Order = S.Context.getIntegerTypeOrder(OtherIntTy, IntTy);<br>
<br>
+ bool IntSigned = IntTy->hasSignedIntegerRepresentation();<br>
<br>
+ bool OtherIntSigned = OtherIntTy->hasSignedIntegerRepresentation();<br>
<br>
+<br>
<br>
+ if (CstInt) {<br>
<br>
+ // If the scalar is constant and is of a higher order and has more active<br>
<br>
+ // bits that the vector element type, reject it.<br>
<br>
+ unsigned NumBits = IntSigned<br>
<br>
+ ? (Result.isNegative() ? Result.getMinSignedBits()<br>
<br>
+ : Result.getActiveBits())<br>
<br>
+ : Result.getActiveBits();<br>
<br>
+ if (Order < 0 && S.Context.getIntWidth(OtherIntTy) < NumBits)<br>
<br>
+ return true;<br>
<br>
+<br>
<br>
+ // If the signedness of the scalar type and the vector element type<br>
<br>
+ // differs and the number of bits is greater than that of the vector<br>
<br>
+ // element reject it.<br>
<br>
+ return (IntSigned != OtherIntSigned &&<br>
<br>
+ NumBits > S.Context.getIntWidth(OtherIntTy));<br>
<br>
+ }<br>
<br>
+<br>
<br>
+ // Reject cases where the value of the scalar is not constant and it's<br>
<br>
+ // order is greater than that of the vector element type.<br>
<br>
+ return (Order < 0);<br>
<br>
+}<br>
<br>
+<br>
<br>
+/// Test if a (constant) integer Int can be casted to floating point type<br>
<br>
+/// FloatTy without losing precision.<br>
<br>
+static bool canConvertIntTyToFloatTy(Sema &S, ExprResult *Int,<br>
<br>
+ QualType FloatTy) {<br>
<br>
+ QualType IntTy = Int->get()->getType().getUnqualifiedType();<br>
<br>
+<br>
<br>
+ // Determine if the integer constant can be expressed as a floating point<br>
<br>
+ // number of the appropiate type.<br>
<br>
+ llvm::APSInt Result;<br>
<br>
+ bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context);<br>
<br>
+ uint64_t Bits = 0;<br>
<br>
+ if (CstInt) {<br>
<br>
+ // Reject constants that would be truncated if they were converted to<br>
<br>
+ // the floating point type. Test by simple to/from conversion.<br>
<br>
+ // FIXME: Ideally the conversion to an APFloat and from an APFloat<br>
<br>
+ // could be avoided if there was a convertFromAPInt method<br>
<br>
+ // which could signal back if implicit truncation occurred.<br>
<br>
+ llvm::APFloat Float(S.Context.getFloatTypeSemantics(FloatTy));<br>
<br>
+ Float.convertFromAPInt(Result, IntTy->hasSignedIntegerRepresentation(),<br>
<br>
+ llvm::APFloat::rmTowardZero);<br>
<br>
+ llvm::APSInt ConvertBack(S.Context.getIntWidth(IntTy),<br>
<br>
+ !IntTy->hasSignedIntegerRepresentation());<br>
<br>
+ bool Ignored = false;<br>
<br>
+ Float.convertToInteger(ConvertBack, llvm::APFloat::rmNearestTiesToEven,<br>
<br>
+ &Ignored);<br>
<br>
+ if (Result != ConvertBack)<br>
<br>
+ return true;<br>
<br>
+ } else {<br>
<br>
+ // Reject types that cannot be fully encoded into the mantissa of<br>
<br>
+ // the float.<br>
<br>
+ Bits = S.Context.getTypeSize(IntTy);<br>
<br>
+ unsigned FloatPrec = llvm::APFloat::semanticsPrecision(<br>
<br>
+ S.Context.getFloatTypeSemantics(FloatTy));<br>
<br>
+ if (Bits > FloatPrec)<br>
<br>
+ return true;<br>
<br>
+ }<br>
<br>
+<br>
<br>
+ return false;<br>
<br>
+}<br>
<br>
+<br>
<br>
+/// Attempt to convert and splat Scalar into a vector whose types matches<br>
<br>
+/// Vector following GCC conversion rules. The rule is that implicit<br>
<br>
+/// conversion can occur when Scalar can be casted to match Vector's element<br>
<br>
+/// type without causing truncation of Scalar.<br>
<br>
+static bool tryGCCVectorConvertAndSplat(Sema &S, ExprResult *Scalar,<br>
<br>
+ ExprResult *Vector) {<br>
<br>
+ QualType ScalarTy = Scalar->get()->getType().getUnqualifiedType();<br>
<br>
+ QualType VectorTy = Vector->get()->getType().getUnqualifiedType();<br>
<br>
+ const VectorType *VT = VectorTy->getAs<VectorType>();<br>
<br>
+<br>
<br>
+ assert(!isa<ExtVectorType>(VT) &&<br>
<br>
+ "ExtVectorTypes should not be handled here!");<br>
<br>
+<br>
<br>
+ QualType VectorEltTy = VT->getElementType();<br>
<br>
+<br>
<br>
+ // Reject cases where the vector element type or the scalar element type are<br>
<br>
+ // not integral or floating point types.<br>
<br>
+ if (!VectorEltTy->isArithmeticType() || !ScalarTy->isArithmeticType())<br>
<br>
+ return true;<br>
<br>
+<br>
<br>
+ // The conversion to apply to the scalar before splatting it,<br>
<br>
+ // if necessary.<br>
<br>
+ CastKind ScalarCast = CK_Invalid;<br>
<br>
+<br>
<br>
+ // Accept cases where the vector elements are integers and the scalar is<br>
<br>
+ // an integer.<br>
<br>
+ // FIXME: Notionally if the scalar was a floating point value with a precise<br>
<br>
+ // integral representation, we could cast it to an appropriate integer<br>
<br>
+ // type and then perform the rest of the checks here. GCC will perform<br>
<br>
+ // this conversion in some cases as determined by the input language.<br>
<br>
+ // We should accept it on a language independent basis.<br>
<br>
+ if (VectorEltTy->isIntegralType(S.Context) &&<br>
<br>
+ ScalarTy->isIntegralType(S.Context) &&<br>
<br>
+ S.Context.getIntegerTypeOrder(VectorEltTy, ScalarTy)) {<br>
<br>
+<br>
<br>
+ if (canConvertIntToOtherIntTy(S, Scalar, VectorEltTy))<br>
<br>
+ return true;<br>
<br>
+<br>
<br>
+ ScalarCast = CK_IntegralCast;<br>
<br>
+ } else if (VectorEltTy->isRealFloatingType()) {<br>
<br>
+ if (ScalarTy->isRealFloatingType()) {<br>
<br>
+<br>
<br>
+ // Reject cases where the scalar type is not a constant and has a higher<br>
<br>
+ // Order than the vector element type.<br>
<br>
+ llvm::APFloat Result(0.0);<br>
<br>
+ bool CstScalar = Scalar->get()->EvaluateAsFloat(Result, S.Context);<br>
<br>
+ int Order = S.Context.getFloatingTypeOrder(VectorEltTy, ScalarTy);<br>
<br>
+ if (!CstScalar && Order < 0)<br>
<br>
+ return true;<br>
<br>
+<br>
<br>
+ // If the scalar cannot be safely casted to the vector element type,<br>
<br>
+ // reject it.<br>
<br>
+ if (CstScalar) {<br>
<br>
+ bool Truncated = false;<br>
<br>
+ Result.convert(S.Context.getFloatTypeSemantics(VectorEltTy),<br>
<br>
+ llvm::APFloat::rmNearestTiesToEven, &Truncated);<br>
<br>
+ if (Truncated)<br>
<br>
+ return true;<br>
<br>
+ }<br>
<br>
+<br>
<br>
+ ScalarCast = CK_FloatingCast;<br>
<br>
+ } else if (ScalarTy->isIntegralType(S.Context)) {<br>
<br>
+ if (canConvertIntTyToFloatTy(S, Scalar, VectorEltTy))<br>
<br>
+ return true;<br>
<br>
+<br>
<br>
+ ScalarCast = CK_IntegralToFloating;<br>
<br>
+ } else<br>
<br>
+ return true;<br>
<br>
+ }<br>
<br>
+<br>
<br>
+ // Adjust scalar if desired.<br>
<br>
+ if (Scalar) {<br>
<br>
+ if (ScalarCast != CK_Invalid)<br>
<br>
+ *Scalar = S.ImpCastExprToType(Scalar->get(), VectorEltTy, ScalarCast);<br>
<br>
+ *Scalar = S.ImpCastExprToType(Scalar->get(), VectorTy, CK_VectorSplat);<br>
<br>
+ }<br>
<br>
+ return false;<br>
<br>
+}<br>
<br>
+<br>
<br>
QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,<br>
<br>
SourceLocation Loc, bool IsCompAssign,<br>
<br>
bool AllowBothBool,<br>
<br>
@@ -8146,19 +8329,29 @@ QualType Sema::CheckVectorOperands(ExprR<br>
<br>
}<br>
<br>
}<br>
<br>
<br>
<br>
- // If there's an ext-vector type and a scalar, try to convert the scalar to<br>
<br>
+ // If there's a vector type and a scalar, try to convert the scalar to<br>
<br>
// the vector element type and splat.<br>
<br>
- // FIXME: this should also work for regular vector types as supported in GCC.<br>
<br>
- if (!RHSVecType && isa<ExtVectorType>(LHSVecType)) {<br>
<br>
- if (!tryVectorConvertAndSplat(*this, &RHS, RHSType,<br>
<br>
- LHSVecType->getElementType(), LHSType))<br>
<br>
- return LHSType;<br>
<br>
+ if (!RHSVecType) {<br>
<br>
+ if (isa<ExtVectorType>(LHSVecType)) {<br>
<br>
+ if (!tryVectorConvertAndSplat(*this, &RHS, RHSType,<br>
<br>
+ LHSVecType->getElementType(), LHSType))<br>
<br>
+ return LHSType;<br>
<br>
+ } else {<br>
<br>
+ if (!tryGCCVectorConvertAndSplat(*this, &RHS, &LHS))<br>
<br>
+ return LHSType;<br>
<br>
+ }<br>
<br>
}<br>
<br>
- if (!LHSVecType && isa<ExtVectorType>(RHSVecType)) {<br>
<br>
- if (!tryVectorConvertAndSplat(*this, (IsCompAssign ? nullptr : &LHS),<br>
<br>
- LHSType, RHSVecType->getElementType(),<br>
<br>
- RHSType))<br>
<br>
- return RHSType;<br>
<br>
+ if (!LHSVecType) {<br>
<br>
+ if (isa<ExtVectorType>(RHSVecType)) {<br>
<br>
+ if (!tryVectorConvertAndSplat(*this, (IsCompAssign ? nullptr : &LHS),<br>
<br>
+ LHSType, RHSVecType->getElementType(),<br>
<br>
+ RHSType))<br>
<br>
+ return RHSType;<br>
<br>
+ } else {<br>
<br>
+ if (LHS.get()->getValueKind() == VK_LValue ||<br>
<br>
+ !tryGCCVectorConvertAndSplat(*this, &LHS, &RHS))<br>
<br>
+ return RHSType;<br>
<br>
+ }<br>
<br>
}<br>
<br>
<br>
<br>
// FIXME: The code below also handles conversion between vectors and<br>
<br>
@@ -8211,6 +8404,22 @@ QualType Sema::CheckVectorOperands(ExprR<br>
<br>
return QualType();<br>
<br>
}<br>
<br>
<br>
<br>
+<br>
<br>
+ // If there is a vector type that is not a ExtVector and a scalar, we reach<br>
<br>
+ // this point if scalar could not be converted to the vector's element type<br>
<br>
+ // without truncation.<br>
<br>
+ if ((RHSVecType && !isa<ExtVectorType>(RHSVecType)) ||<br>
<br>
+ (LHSVecType && !isa<ExtVectorType>(LHSVecType))) {<br>
<br>
+ QualType Scalar = LHSVecType ? RHSType : LHSType;<br>
<br>
+ QualType Vector = LHSVecType ? LHSType : RHSType;<br>
<br>
+ unsigned ScalarOrVector = LHSVecType && RHSVecType ? 1 : 0;<br>
<br>
+ Diag(Loc,<br>
<br>
+ diag::err_typecheck_vector_not_convertable_implict_truncation)<br>
<br>
+ << ScalarOrVector << Scalar << Vector;<br>
<br>
+<br>
<br>
+ return QualType();<br>
<br>
+ }<br>
<br>
+<br>
<br>
// Otherwise, use the generic diagnostic.<br>
<br>
Diag(Loc, diag::err_typecheck_vector_not_convertable)<br>
<br>
<< LHSType << RHSType<br>
<br>
@@ -9830,6 +10039,12 @@ QualType Sema::CheckVectorLogicalOperand<br>
<br>
if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion < 120 &&<br>
<br>
vType->hasFloatingRepresentation())<br>
<br>
return InvalidOperands(Loc, LHS, RHS);<br>
<br>
+ // FIXME: The check for C++ here is for GCC compatibility. GCC rejects the<br>
<br>
+ // usage of the logical operators && and || with vectors in C. This<br>
<br>
+ // check could be notionally dropped.<br>
<br>
+ if (!getLangOpts().CPlusPlus &&<br>
<br>
+ !(isa<ExtVectorType>(vType->getAs<VectorType>())))<br>
<br>
+ return InvalidLogicalVectorOperands(Loc, LHS, RHS);<br>
<br>
<br>
<br>
return GetSignedVectorType(LHS.get()->getType());<br>
<br>
}<br>
<br>
@@ -11773,6 +11988,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(So<br>
<br>
resultType = GetSignedVectorType(resultType);<br>
<br>
break;<br>
<br>
} else {<br>
<br>
+ // FIXME: GCC's vector extension permits the usage of '!' with a vector<br>
<br>
+ // type in C++. We should allow that here too.<br>
<br>
return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)<br>
<br>
<< resultType << Input.get()->getSourceRange());<br>
<br>
}<br>
<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp<br>
<br>
URL:<br>
<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=302935&r1=302934&r2=302935&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=302935&r1=302934&r2=302935&view=diff</a><br>
<br>
==============================================================================<br>
<br>
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)<br>
<br>
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri May 12 14:11:06 2017<br>
<br>
@@ -5356,6 +5356,15 @@ QualType Sema::CXXCheckConditionalOperan<br>
<br>
<br>
<br>
// C++11 [expr.cond]p1<br>
<br>
// The first expression is contextually converted to bool.<br>
<br>
+ //<br>
<br>
+ // FIXME; GCC's vector extension permits the use of a?b:c where the type of<br>
<br>
+ // a is that of a integer vector with the same number of elements and<br>
<br>
+ // size as the vectors of b and c. If one of either b or c is a scalar<br>
<br>
+ // it is implicitly converted to match the type of the vector.<br>
<br>
+ // Otherwise the expression is ill-formed. If both b and c are scalars,<br>
<br>
+ // then b and c are checked and converted to the type of a if possible.<br>
<br>
+ // Unlike the OpenCL ?: operator, the expression is evaluated as<br>
<br>
+ // (a[0] != 0 ? b[0] : c[0], .. , a[n] != 0 ? b[n] : c[n]).<br>
<br>
if (!Cond.get()->isTypeDependent()) {<br>
<br>
ExprResult CondRes = CheckCXXBooleanCondition(Cond.get());<br>
<br>
if (CondRes.isInvalid())<br>
<br>
<br>
<br>
Modified: cfe/trunk/test/Sema/vector-cast.c<br>
<br>
URL:<br>
<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vector-cast.c?rev=302935&r1=302934&r2=302935&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vector-cast.c?rev=302935&r1=302934&r2=302935&view=diff</a><br>
<br>
==============================================================================<br>
<br>
--- cfe/trunk/test/Sema/vector-cast.c (original)<br>
<br>
+++ cfe/trunk/test/Sema/vector-cast.c Fri May 12 14:11:06 2017<br>
<br>
@@ -53,9 +53,8 @@ void f4() {<br>
<br>
float2 f2;<br>
<br>
double d, a, b, c;<br>
<br>
float64x2_t v = {0.0, 1.0};<br>
<br>
- // FIXME: These diagnostics are inaccurate: should complain that 'double' to vector 'float2' involves truncation<br>
<br>
- f2 += d; // expected-error {{cannot convert between vector values of different size ('float2' (vector of 2 'float' values) and 'double')}}<br>
<br>
- d += f2; // expected-error {{cannot convert between vector values of different size}}<br>
<br>
+ f2 += d; // expected-error {{cannot convert between scalar type 'double' and vector type 'float2' (vector of 2 'float' values) as implicit conversion would cause truncation}}<br>
<br>
+ d += f2; // expected-error {{assigning to 'double' from incompatible type 'float2' (vector of 2 'float' values)}}<br>
<br>
a = 3.0 + vget_low_f64(v);<br>
<br>
b = vget_low_f64(v) + 3.0;<br>
<br>
c = vget_low_f64(v);<br>
<br>
<br>
<br>
Added: cfe/trunk/test/Sema/vector-gcc-compat.c<br>
<br>
URL:<br>
<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vector-gcc-compat.c?rev=302935&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vector-gcc-compat.c?rev=302935&view=auto</a><br>
<br>
==============================================================================<br>
<br>
--- cfe/trunk/test/Sema/vector-gcc-compat.c (added)<br>
<br>
+++ cfe/trunk/test/Sema/vector-gcc-compat.c Fri May 12 14:11:06 2017<br>
<br>
@@ -0,0 +1,330 @@<br>
<br>
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything<br>
<br>
+<br>
<br>
+// Test the compatibility of clang's vector extensions with gcc's vector<br>
<br>
+// extensions for C. Notably &&, ||, ?: and ! are not available.<br>
<br>
+typedef long long v2i64 __attribute__((vector_size(16)));<br>
<br>
+typedef int v2i32 __attribute__((vector_size(8)));<br>
<br>
+typedef short v2i16 __attribute__((vector_size(4)));<br>
<br>
+typedef char v2i8 __attribute__((vector_size(2)));<br>
<br>
+<br>
<br>
+typedef unsigned long long v2u64 __attribute__((vector_size(16)));<br>
<br>
+typedef unsigned int v2u32 __attribute__((vector_size(8)));<br>
<br>
+typedef unsigned short v2u16 __attribute__((vector_size(4)));<br>
<br>
+typedef unsigned char v2u8 __attribute__((vector_size(2)));<br>
<br>
+<br>
<br>
+typedef float v4f32 __attribute__((vector_size(16)));<br>
<br>
+typedef double v2f64 __attribute__((vector_size(16)));<br>
<br>
+typedef double v4f64 __attribute__((vector_size(32)));<br>
<br>
+typedef int v4i32 __attribute((vector_size(16)));<br>
<br>
+<br>
<br>
+void arithmeticTest(void);<br>
<br>
+void logicTest(void);<br>
<br>
+void comparisonTest(void);<br>
<br>
+void floatTestSignedType(char a, short b, int c, long long d);<br>
<br>
+void floatTestUnsignedType(unsigned char a, unsigned short b, unsigned int c,<br>
<br>
+ unsigned long long d);<br>
<br>
+void floatTestConstant(void);<br>
<br>
+void intTestType(char a, short b, int c, long long d);<br>
<br>
+void intTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,<br>
<br>
+ unsigned long long d);<br>
<br>
+void uintTestType(char a, short b, int c, long long d);<br>
<br>
+void uintTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,<br>
<br>
+ unsigned long long d);<br>
<br>
+void uintTestConstant(v2u64 v2u64_a, v2u32 v2u32_a, v2u16 v2u16_a, v2u8 v2u8_a);<br>
<br>
+void intTestConstant(v2i64 v2i64_a, v2i32 v2i32_a, v2i16 v2i16_a, v2i8 v2i8_a);<br>
<br>
+<br>
<br>
+void arithmeticTest(void) {<br>
<br>
+ v2i64 v2i64_a = (v2i64){0, 1};<br>
<br>
+ v2i64 v2i64_r;<br>
<br>
+<br>
<br>
+ v2i64_r = v2i64_a + 1;<br>
<br>
+ v2i64_r = v2i64_a - 1;<br>
<br>
+ v2i64_r = v2i64_a * 1;<br>
<br>
+ v2i64_r = v2i64_a / 1;<br>
<br>
+ v2i64_r = v2i64_a % 1;<br>
<br>
+<br>
<br>
+ v2i64_r = 1 + v2i64_a;<br>
<br>
+ v2i64_r = 1 - v2i64_a;<br>
<br>
+ v2i64_r = 1 * v2i64_a;<br>
<br>
+ v2i64_r = 1 / v2i64_a;<br>
<br>
+ v2i64_r = 1 % v2i64_a;<br>
<br>
+<br>
<br>
+ v2i64_a += 1;<br>
<br>
+ v2i64_a -= 1;<br>
<br>
+ v2i64_a *= 1;<br>
<br>
+ v2i64_a /= 1;<br>
<br>
+ v2i64_a %= 1;<br>
<br>
+}<br>
<br>
+<br>
<br>
+void comparisonTest(void) {<br>
<br>
+ v2i64 v2i64_a = (v2i64){0, 1};<br>
<br>
+ v2i64 v2i64_r;<br>
<br>
+<br>
<br>
+ v2i64_r = v2i64_a == 1;<br>
<br>
+ v2i64_r = v2i64_a != 1;<br>
<br>
+ v2i64_r = v2i64_a < 1;<br>
<br>
+ v2i64_r = v2i64_a > 1;<br>
<br>
+ v2i64_r = v2i64_a <= 1;<br>
<br>
+ v2i64_r = v2i64_a >= 1;<br>
<br>
+<br>
<br>
+ v2i64_r = 1 == v2i64_a;<br>
<br>
+ v2i64_r = 1 != v2i64_a;<br>
<br>
+ v2i64_r = 1 < v2i64_a;<br>
<br>
+ v2i64_r = 1 > v2i64_a;<br>
<br>
+ v2i64_r = 1 <= v2i64_a;<br>
<br>
+ v2i64_r = 1 >= v2i64_a;<br>
<br>
+}<br>
<br>
+<br>
<br>
+void logicTest(void) {<br>
<br>
+ v2i64 v2i64_a = (v2i64){0, 1};<br>
<br>
+ v2i64 v2i64_b = (v2i64){2, 1};<br>
<br>
+ v2i64 v2i64_c = (v2i64){3, 1};<br>
<br>
+ v2i64 v2i64_r;<br>
<br>
+<br>
<br>
+ v2i64_r = !v2i64_a; // expected-error {{invalid argument type 'v2i64' (vector of 2 'long long' values) to unary expression}}<br>
<br>
+ v2i64_r = ~v2i64_a;<br>
<br>
+<br>
<br>
+ v2i64_r = v2i64_a ? v2i64_b : v2i64_c; // expected-error {{used type 'v2i64' (vector of 2 'long long' values) where arithmetic or pointer type is required}}<br>
<br>
+<br>
<br>
+ v2i64_r = v2i64_a & 1;<br>
<br>
+ v2i64_r = v2i64_a | 1;<br>
<br>
+ v2i64_r = v2i64_a ^ 1;<br>
<br>
+<br>
<br>
+ v2i64_r = 1 & v2i64_a;<br>
<br>
+ v2i64_r = 1 | v2i64_a;<br>
<br>
+ v2i64_r = 1 ^ v2i64_a;<br>
<br>
+<br>
<br>
+ v2i64_a &= 1;<br>
<br>
+ v2i64_a |= 1;<br>
<br>
+ v2i64_a ^= 1;<br>
<br>
+<br>
<br>
+ v2i64_r = v2i64_a && 1; // expected-error {{logical expression with vector type 'v2i64' (vector of 2 'long long' values) and non-vector type 'int' is only supported in C++}}<br>
<br>
+ v2i64_r = v2i64_a || 1; // expected-error {{logical expression with vector type 'v2i64' (vector of 2 'long long' values) and non-vector type 'int' is only supported in C++}}<br>
<br>
+<br>
<br>
+ v2i64_r = v2i64_a && v2i64_a; // expected-error {{logical expression with vector types 'v2i64' (vector of 2 'long long' values) and 'v2i64' is only supported in C++}}<br>
<br>
+ v2i64_r = v2i64_a || v2i64_a; // expected-error {{logical expression with vector types 'v2i64' (vector of 2 'long long' values) and 'v2i64' is only supported in C++}}<br>
<br>
+<br>
<br>
+ v2i64_r = v2i64_a << 1;<br>
<br>
+ v2i64_r = v2i64_a >> 1;<br>
<br>
+<br>
<br>
+ v2i64_r = 1 << v2i64_a;<br>
<br>
+ v2i64_r = 1 >> v2i64_a;<br>
<br>
+<br>
<br>
+ v2i64_a <<= 1;<br>
<br>
+ v2i64_a >>= 1;<br>
<br>
+}<br>
<br>
+<br>
<br>
+// For operations with floating point types, we check that interger constants<br>
<br>
+// can be respresented, or failing that checking based on the integer types.<br>
<br>
+void floatTestConstant(void) {<br>
<br>
+ // Test that constants added to floats must be expressible as floating point<br>
<br>
+ // numbers.<br>
<br>
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};<br>
<br>
+ v4f32_a = v4f32_a + 1;<br>
<br>
+ v4f32_a = v4f32_a + 0xFFFFFF;<br>
<br>
+ v4f32_a = v4f32_a + (-1567563LL);<br>
<br>
+ v4f32_a = v4f32_a + (16777208);<br>
<br>
+ v4f32_a = v4f32_a + (16777219); // expected-error {{cannot convert between scalar type 'int' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}<br>
<br>
+}<br>
<br>
+<br>
<br>
+void floatTestConstantComparison(void);<br>
<br>
+void doubleTestConstantComparison(void);<br>
<br>
+<br>
<br>
+void floatTestConstantComparison(void) {<br>
<br>
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};<br>
<br>
+ v4i32 v4i32_r;<br>
<br>
+ v4i32_r = v4f32_a > 0.4f;<br>
<br>
+ v4i32_r = v4f32_a >= 0.4f;<br>
<br>
+ v4i32_r = v4f32_a < 0.4f;<br>
<br>
+ v4i32_r = v4f32_a <= 0.4f;<br>
<br>
+ v4i32_r = v4f32_a == 0.4f; // expected-warning {{comparing floating point with == or != is unsafe}}<br>
<br>
+ v4i32_r = v4f32_a != 0.4f; // expected-warning {{comparing floating point with == or != is unsafe}}<br>
<br>
+}<br>
<br>
+<br>
<br>
+void doubleTestConstantComparison(void) {<br>
<br>
+ v2f64 v2f64_a = {0.4, 0.4};<br>
<br>
+ v2i64 v2i64_r;<br>
<br>
+ v2i64_r = v2f64_a > 0.4;<br>
<br>
+ v2i64_r = v2f64_a >= 0.4;<br>
<br>
+ v2i64_r = v2f64_a < 0.4;<br>
<br>
+ v2i64_r = v2f64_a <= 0.4;<br>
<br>
+ v2i64_r = v2f64_a == 0.4; // expected-warning {{comparing floating point with == or != is unsafe}}<br>
<br>
+ v2i64_r = v2f64_a != 0.4; // expected-warning {{comparing floating point with == or != is unsafe}}<br>
<br>
+}<br>
<br>
+<br>
<br>
+void floatTestUnsignedType(unsigned char a, unsigned short b, unsigned int c,<br>
<br>
+ unsigned long long d) {<br>
<br>
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};<br>
<br>
+ v4f64 v4f64_b = {0.4, 0.4, 0.4, 0.4};<br>
<br>
+<br>
<br>
+ v4f32_a = v4f32_a + a;<br>
<br>
+ v4f32_a = v4f32_a + b;<br>
<br>
+ v4f32_a = v4f32_a + c; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}<br>
<br>
+ v4f32_a = v4f32_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}<br>
<br>
+<br>
<br>
+ v4f64_b = v4f64_b + a;<br>
<br>
+ v4f64_b = v4f64_b + b;<br>
<br>
+ v4f64_b = v4f64_b + c;<br>
<br>
+ v4f64_b = v4f64_b + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v4f64' (vector of 4 'double' values) as implicit conversion would cause truncation}}<br>
<br>
+}<br>
<br>
+<br>
<br>
+void floatTestSignedType(char a, short b, int c, long long d) {<br>
<br>
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};<br>
<br>
+ v4f64 v4f64_b = {0.4, 0.4, 0.4, 0.4};<br>
<br>
+<br>
<br>
+ v4f32_a = v4f32_a + a;<br>
<br>
+ v4f32_a = v4f32_a + b;<br>
<br>
+ v4f32_a = v4f32_a + c; // expected-error {{cannot convert between scalar type 'int' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}<br>
<br>
+ v4f32_a = v4f32_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}<br>
<br>
+<br>
<br>
+ v4f64_b = v4f64_b + a;<br>
<br>
+ v4f64_b = v4f64_b + b;<br>
<br>
+ v4f64_b = v4f64_b + c;<br>
<br>
+ v4f64_b = v4f64_b + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v4f64' (vector of 4 'double' values) as implicit conversion would cause truncation}}<br>
<br>
+}<br>
<br>
+<br>
<br>
+void intTestType(char a, short b, int c, long long d) {<br>
<br>
+ v2i64 v2i64_a = {1, 2};<br>
<br>
+ v2i32 v2i32_a = {1, 2};<br>
<br>
+ v2i16 v2i16_a = {1, 2};<br>
<br>
+ v2i8 v2i8_a = {1, 2};<br>
<br>
+<br>
<br>
+ v2i64_a = v2i64_a + d;<br>
<br>
+ v2i64_a = v2i64_a + c;<br>
<br>
+ v2i64_a = v2i64_a + b;<br>
<br>
+ v2i64_a = v2i64_a + a;<br>
<br>
+<br>
<br>
+ v2i32_a = v2i32_a + d; // expected-warning {{implicit conversion loses integer precision: 'long long' to 'v2i32' (vector of 2 'int' values)}}<br>
<br>
+ v2i32_a = v2i32_a + c;<br>
<br>
+ v2i32_a = v2i32_a + b;<br>
<br>
+ v2i32_a = v2i32_a + a;<br>
<br>
+<br>
<br>
+ v2i16_a = v2i16_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v2i16' (vector of 2 'short' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2i16_a = v2i16_a + c; // expected-warning {{implicit conversion loses integer precision: 'int' to 'v2i16' (vector of 2 'short' values)}}<br>
<br>
+ v2i16_a = v2i16_a + b;<br>
<br>
+ v2i16_a = v2i16_a + a;<br>
<br>
+<br>
<br>
+ v2i8_a = v2i8_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2i8_a = v2i8_a + c; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2i8_a = v2i8_a + b; // expected-warning {{implicit conversion loses integer precision: 'short' to 'v2i8' (vector of 2 'char' values)}}<br>
<br>
+ v2i8_a = v2i8_a + a;<br>
<br>
+}<br>
<br>
+<br>
<br>
+void intTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,<br>
<br>
+ unsigned long long d) {<br>
<br>
+ v2i64 v2i64_a = {1, 2};<br>
<br>
+ v2i32 v2i32_a = {1, 2};<br>
<br>
+ v2i16 v2i16_a = {1, 2};<br>
<br>
+ v2i8 v2i8_a = {1, 2};<br>
<br>
+<br>
<br>
+ v2i64_a = v2i64_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2i64' (vector of 2 'long long' values) as implicit conversion would cause truncation}}<br>
<br>
+<br>
<br>
+ v2i64_a = v2i64_a + c;<br>
<br>
+ v2i64_a = v2i64_a + b;<br>
<br>
+ v2i64_a = v2i64_a + a;<br>
<br>
+<br>
<br>
+ v2i32_a = v2i32_a + d; // expected-warning {{implicit conversion loses integer precision: 'unsigned long long' to 'v2i32' (vector of 2 'int' values)}}<br>
<br>
+ v2i32_a = v2i32_a + c; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2i32' (vector of 2 'int' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2i32_a = v2i32_a + b;<br>
<br>
+ v2i32_a = v2i32_a + a;<br>
<br>
+<br>
<br>
+ v2i16_a = v2i16_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2i16' (vector of 2 'short' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2i16_a = v2i16_a + c; // expected-warning {{implicit conversion loses integer precision: 'unsigned int' to 'v2i16' (vector of 2 'short' values)}}<br>
<br>
+ v2i16_a = v2i16_a + b; // expected-error {{cannot convert between scalar type 'unsigned short' and vector type 'v2i16' (vector of 2 'short' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2i16_a = v2i16_a + a;<br>
<br>
+<br>
<br>
+ v2i8_a = v2i8_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2i8_a = v2i8_a + c; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2i8_a = v2i8_a + b; // expected-warning {{implicit conversion loses integer precision: 'unsigned short' to 'v2i8' (vector of 2 'char' values)}}<br>
<br>
+ v2i8_a = v2i8_a + a; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}<br>
<br>
+}<br>
<br>
+<br>
<br>
+void uintTestType(char a, short b, int c, long long d) {<br>
<br>
+ v2u64 v2u64_a = {1, 2};<br>
<br>
+ v2u32 v2u32_a = {1, 2};<br>
<br>
+ v2u16 v2u16_a = {1, 2};<br>
<br>
+ v2u8 v2u8_a = {1, 2};<br>
<br>
+<br>
<br>
+ v2u64_a = v2u64_a + d; // expected-warning {{implicit conversion changes signedness: 'long long' to 'v2u64' (vector of 2 'unsigned long long' values)}}<br>
<br>
+ v2u64_a = v2u64_a + c; // expected-warning {{implicit conversion changes signedness: 'int' to 'v2u64' (vector of 2 'unsigned long long' values)}}<br>
<br>
+ v2u64_a = v2u64_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u64' (vector of 2 'unsigned long long' values)}}<br>
<br>
+ v2u64_a = v2u64_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u64' (vector of 2 'unsigned long long' values)}}<br>
<br>
+<br>
<br>
+ v2u32_a = v2u32_a + d; // expected-warning {{implicit conversion loses integer precision: 'long long' to 'v2u32' (vector of 2 'unsigned int' values)}}<br>
<br>
+ v2u32_a = v2u32_a + c; // expected-warning {{implicit conversion changes signedness: 'int' to 'v2u32' (vector of 2 'unsigned int' values)}}<br>
<br>
+ v2u32_a = v2u32_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u32' (vector of 2 'unsigned int' values)}}<br>
<br>
+ v2u32_a = v2u32_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u32' (vector of 2 'unsigned int' values)}}<br>
<br>
+<br>
<br>
+ v2u16_a = v2u16_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v2u16' (vector of 2 'unsigned short' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2u16_a = v2u16_a + c; // expected-warning {{implicit conversion loses integer precision: 'int' to 'v2u16' (vector of 2 'unsigned short' values)}}<br>
<br>
+ v2u16_a = v2u16_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u16' (vector of 2 'unsigned short' values)}}<br>
<br>
+ v2u16_a = v2u16_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u16' (vector of 2 'unsigned short' values)}}<br>
<br>
+<br>
<br>
+ v2u8_a = v2u8_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2u8_a = v2u8_a + c; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2u8_a = v2u8_a + b; // expected-warning {{implicit conversion loses integer precision: 'short' to 'v2u8' (vector of 2 'unsigned char' values)}}<br>
<br>
+ v2u8_a = v2u8_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u8' (vector of 2 'unsigned char' values)}}<br>
<br>
+}<br>
<br>
+<br>
<br>
+void uintTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,<br>
<br>
+ unsigned long long d) {<br>
<br>
+ v2u64 v2u64_a = {1, 2};<br>
<br>
+ v2u32 v2u32_a = {1, 2};<br>
<br>
+ v2u16 v2u16_a = {1, 2};<br>
<br>
+ v2u8 v2u8_a = {1, 2};<br>
<br>
+<br>
<br>
+ v2u64_a = v2u64_a + d;<br>
<br>
+ v2u64_a = v2u64_a + c;<br>
<br>
+ v2u64_a = v2u64_a + b;<br>
<br>
+ v2u64_a = v2u64_a + a;<br>
<br>
+<br>
<br>
+ v2u32_a = v2u32_a + d; // expected-warning {{implicit conversion loses integer precision: 'unsigned long long' to 'v2u32' (vector of 2 'unsigned int' values)}}<br>
<br>
+ v2u32_a = v2u32_a + c;<br>
<br>
+ v2u32_a = v2u32_a + b;<br>
<br>
+ v2u32_a = v2u32_a + a;<br>
<br>
+<br>
<br>
+ v2u16_a = v2u16_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2u16' (vector of 2 'unsigned short' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2u16_a = v2u16_a + c; // expected-warning {{implicit conversion loses integer precision: 'unsigned int' to 'v2u16' (vector of 2 'unsigned short' values)}}<br>
<br>
+ v2u16_a = v2u16_a + b;<br>
<br>
+ v2u16_a = v2u16_a + a;<br>
<br>
+<br>
<br>
+ v2u8_a = v2u8_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2u8_a = v2u8_a + c; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2u8_a = v2u8_a + b; // expected-warning {{implicit conversion loses integer precision: 'unsigned short' to 'v2u8' (vector of 2 'unsigned char' values)}}<br>
<br>
+ v2u8_a = v2u8_a + a;<br>
<br>
+}<br>
<br>
+<br>
<br>
+void uintTestConstant(v2u64 v2u64_a, v2u32 v2u32_a, v2u16 v2u16_a,<br>
<br>
+ v2u8 v2u8_a) {<br>
<br>
+ v2u64_a = v2u64_a + 0xFFFFFFFFFFFFFFFF;<br>
<br>
+ v2u32_a = v2u32_a + 0xFFFFFFFF;<br>
<br>
+ v2u16_a = v2u16_a + 0xFFFF;<br>
<br>
+ v2u8_a = v2u8_a + 0xFF;<br>
<br>
+<br>
<br>
+ v2u32_a = v2u32_a + 0x1FFFFFFFF; // expected-warning {{implicit conversion from 'long' to 'v2u32' (vector of 2 'unsigned int' values) changes value from 8589934591 to 4294967295}}<br>
<br>
+ v2u16_a = v2u16_a + 0x1FFFF; // expected-warning {{implicit conversion from 'int' to 'v2u16' (vector of 2 'unsigned short' values) changes value from 131071 to 65535}}<br>
<br>
+ v2u8_a = v2u8_a + 0x1FF; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}<br>
<br>
+}<br>
<br>
+<br>
<br>
+void intTestConstant(v2i64 v2i64_a, v2i32 v2i32_a, v2i16 v2i16_a, v2i8 v2i8_a) {<br>
<br>
+ // Legal upper bounds.<br>
<br>
+ v2i64_a = v2i64_a + (long long)0x7FFFFFFFFFFFFFFF;<br>
<br>
+ v2i32_a = v2i32_a + (int)0x7FFFFFFF;<br>
<br>
+ v2i16_a = v2i16_a + (short)0x7FFF;<br>
<br>
+ v2i8_a = v2i8_a + (char)0x7F;<br>
<br>
+<br>
<br>
+ // Legal lower bounds.<br>
<br>
+ v2i64_a = v2i64_a + (-9223372036854775807);<br>
<br>
+ v2i32_a = v2i32_a +<br>
<a href="tel:(214)%20748-3648" value="+12147483648" target="_blank">(-2147483648</a>);<br>
<br>
+ v2i16_a = v2i16_a + (-32768);<br>
<br>
+ v2i8_a = v2i8_a + (-128);<br>
<br>
+<br>
<br>
+ // One increment/decrement more than the type can hold<br>
<br>
+ v2i32_a = v2i32_a +<br>
<a href="tel:(214)%20748-3648" value="+12147483648" target="_blank">2147483648</a>; // expected-warning {{implicit conversion from 'long' to 'v2i32' (vector of 2 'int' values) changes value from<br>
<a href="tel:(214)%20748-3648" value="+12147483648" target="_blank">2147483648</a> to -<a href="tel:(214)%20748-3648" value="+12147483648" target="_blank">2147483648</a>}}<br>
<br>
+ v2i16_a = v2i16_a + 32768; // expected-warning {{implicit conversion from 'int' to 'v2i16' (vector of 2 'short' values) changes value from 32768 to -32768}}<br>
<br>
+ v2i8_a = v2i8_a + 128; // expected-warning {{implicit conversion from 'int' to 'v2i8' (vector of 2 'char' values) changes value from 128 to -128}}<br>
<br>
+<br>
<br>
+ v2i32_a = v2i32_a +<br>
<a href="tel:(214)%20748-3649" value="+12147483649" target="_blank">(-2147483649</a>); // expected-warning {{implicit conversion from 'long' to 'v2i32' (vector of 2 'int' values) changes value from -<a href="tel:(214)%20748-3649" value="+12147483649" target="_blank">2147483649</a> to<br>
<a href="tel:(214)%20748-3647" value="+12147483647" target="_blank">2147483647</a>}}<br>
<br>
+ v2i16_a = v2i16_a + (-32769); // expected-warning {{implicit conversion from 'int' to 'v2i16' (vector of 2 'short' values) changes value from -32769 to 32767}}<br>
<br>
+ v2i8_a = v2i8_a + (-129); // expected-error {{cannot convert between scalar type 'int' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}<br>
<br>
+}<br>
<br>
<br>
<br>
Added: cfe/trunk/test/Sema/vector-gcc-compat.cpp<br>
<br>
URL:<br>
<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vector-gcc-compat.cpp?rev=302935&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vector-gcc-compat.cpp?rev=302935&view=auto</a><br>
<br>
==============================================================================<br>
<br>
--- cfe/trunk/test/Sema/vector-gcc-compat.cpp (added)<br>
<br>
+++ cfe/trunk/test/Sema/vector-gcc-compat.cpp Fri May 12 14:11:06 2017<br>
<br>
@@ -0,0 +1,328 @@<br>
<br>
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything -std=c++11<br>
<br>
+<br>
<br>
+// Test the compatibility of clang++'s vector extensions with g++'s vector<br>
<br>
+// extensions. In comparison to the extensions available in C, the !, ?:, && and<br>
<br>
+// || operators work on vector types.<br>
<br>
+<br>
<br>
+typedef long long v2i64 __attribute__((vector_size(16))); // expected-warning {{'long long' is incompatible with C++98}}<br>
<br>
+typedef int v2i32 __attribute__((vector_size(8)));<br>
<br>
+typedef short v2i16 __attribute__((vector_size(4)));<br>
<br>
+typedef char v2i8 __attribute__((vector_size(2)));<br>
<br>
+<br>
<br>
+typedef unsigned long long v2u64 __attribute__((vector_size(16))); // expected-warning {{'long long' is incompatible with C++98}}<br>
<br>
+typedef unsigned int v2u32 __attribute__((vector_size(8)));<br>
<br>
+typedef unsigned short v2u16 __attribute__((vector_size(4)));<br>
<br>
+typedef unsigned char v2u8 __attribute__((vector_size(2)));<br>
<br>
+<br>
<br>
+typedef float v4f32 __attribute__((vector_size(16)));<br>
<br>
+typedef double v2f64 __attribute__((vector_size(16)));<br>
<br>
+typedef double v4f64 __attribute__((vector_size(32)));<br>
<br>
+typedef int v4i32 __attribute((vector_size(16)));<br>
<br>
+<br>
<br>
+void arithmeticTest(void);<br>
<br>
+void logicTest(void);<br>
<br>
+void comparisonTest(void);<br>
<br>
+void floatTestSignedType(char a, short b, int c, long long d); // expected-warning {{'long long' is incompatible with C++98}}<br>
<br>
+void floatTestUnsignedType(unsigned char a, unsigned short b, unsigned int c,<br>
<br>
+ unsigned long long d); // expected-warning {{'long long' is incompatible with C++98}}<br>
<br>
+void floatTestConstant(void);<br>
<br>
+void intTestType(char a, short b, int c, long long d); // expected-warning {{'long long' is incompatible with C++98}}<br>
<br>
+void intTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,<br>
<br>
+ unsigned long long d); // expected-warning {{'long long' is incompatible with C++98}}<br>
<br>
+void uintTestType(char a, short b, int c, long long d); // expected-warning {{'long long' is incompatible with C++98}}<br>
<br>
+void uintTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,<br>
<br>
+ unsigned long long d); // expected-warning {{'long long' is incompatible with C++98}}<br>
<br>
+void uintTestConstant(v2u64 v2u64_a, v2u32 v2u32_a, v2u16 v2u16_a, v2u8 v2u8_a);<br>
<br>
+void intTestConstant(v2i64 v2i64_a, v2i32 v2i32_a, v2i16 v2i16_a, v2i8 v2i8_a);<br>
<br>
+<br>
<br>
+void arithmeticTest(void) {<br>
<br>
+ v2i64 v2i64_a = (v2i64){0, 1}; // expected-warning {{compound literals are a C99-specific feature}}<br>
<br>
+ v2i64 v2i64_r;<br>
<br>
+<br>
<br>
+ v2i64_r = v2i64_a + 1;<br>
<br>
+ v2i64_r = v2i64_a - 1;<br>
<br>
+ v2i64_r = v2i64_a * 1;<br>
<br>
+ v2i64_r = v2i64_a / 1;<br>
<br>
+ v2i64_r = v2i64_a % 1;<br>
<br>
+<br>
<br>
+ v2i64_r = 1 + v2i64_a;<br>
<br>
+ v2i64_r = 1 - v2i64_a;<br>
<br>
+ v2i64_r = 1 * v2i64_a;<br>
<br>
+ v2i64_r = 1 / v2i64_a;<br>
<br>
+ v2i64_r = 1 % v2i64_a;<br>
<br>
+<br>
<br>
+ v2i64_a += 1;<br>
<br>
+ v2i64_a -= 1;<br>
<br>
+ v2i64_a *= 1;<br>
<br>
+ v2i64_a /= 1;<br>
<br>
+ v2i64_a %= 1;<br>
<br>
+}<br>
<br>
+<br>
<br>
+void comparisonTest(void) {<br>
<br>
+ v2i64 v2i64_a = (v2i64){0, 1}; // expected-warning {{compound literals are a C99-specific feature}}<br>
<br>
+ v2i64 v2i64_r;<br>
<br>
+<br>
<br>
+ v2i64_r = v2i64_a == 1;<br>
<br>
+ v2i64_r = v2i64_a != 1;<br>
<br>
+ v2i64_r = v2i64_a < 1;<br>
<br>
+ v2i64_r = v2i64_a > 1;<br>
<br>
+ v2i64_r = v2i64_a <= 1;<br>
<br>
+ v2i64_r = v2i64_a >= 1;<br>
<br>
+<br>
<br>
+ v2i64_r = 1 == v2i64_a;<br>
<br>
+ v2i64_r = 1 != v2i64_a;<br>
<br>
+ v2i64_r = 1 < v2i64_a;<br>
<br>
+ v2i64_r = 1 > v2i64_a;<br>
<br>
+ v2i64_r = 1 <= v2i64_a;<br>
<br>
+ v2i64_r = 1 >= v2i64_a;<br>
<br>
+}<br>
<br>
+<br>
<br>
+void logicTest(void) {<br>
<br>
+ v2i64 v2i64_a = (v2i64){0, 1}; // expected-warning {{compound literals are a C99-specific feature}}<br>
<br>
+ v2i64 v2i64_b = (v2i64){2, 1}; // expected-warning {{compound literals are a C99-specific feature}}<br>
<br>
+ v2i64 v2i64_c = (v2i64){3, 1}; // expected-warning {{compound literals are a C99-specific feature}}<br>
<br>
+ v2i64 v2i64_r;<br>
<br>
+<br>
<br>
+ v2i64_r = !v2i64_a; // expected-error {{invalid argument type 'v2i64' (vector of 2 'long long' values) to unary expression}}<br>
<br>
+ v2i64_r = ~v2i64_a;<br>
<br>
+<br>
<br>
+ v2i64_r = v2i64_a ? v2i64_b : v2i64_c; // expected-error {{value of type 'v2i64' (vector of 2 'long long' values) is not contextually convertible to 'bool'}}<br>
<br>
+<br>
<br>
+ v2i64_r = v2i64_a & 1;<br>
<br>
+ v2i64_r = v2i64_a | 1;<br>
<br>
+ v2i64_r = v2i64_a ^ 1;<br>
<br>
+<br>
<br>
+ v2i64_r = 1 & v2i64_a;<br>
<br>
+ v2i64_r = 1 | v2i64_a;<br>
<br>
+ v2i64_r = 1 ^ v2i64_a;<br>
<br>
+ v2i64_a &= 1;<br>
<br>
+ v2i64_a |= 1;<br>
<br>
+ v2i64_a ^= 1;<br>
<br>
+<br>
<br>
+ v2i64_r = v2i64_a && 1;<br>
<br>
+ v2i64_r = v2i64_a || 1;<br>
<br>
+<br>
<br>
+ v2i64_r = v2i64_a << 1;<br>
<br>
+ v2i64_r = v2i64_a >> 1;<br>
<br>
+<br>
<br>
+ v2i64_r = 1 << v2i64_a;<br>
<br>
+ v2i64_r = 1 >> v2i64_a;<br>
<br>
+<br>
<br>
+ v2i64_a <<= 1;<br>
<br>
+ v2i64_a >>= 1;<br>
<br>
+}<br>
<br>
+<br>
<br>
+// For operations with floating point types, we check that interger constants<br>
<br>
+// can be respresented, or failing that checking based on the integer types.<br>
<br>
+void floatTestConstant(void) {<br>
<br>
+ // Test that constants added to floats must be expressible as floating point<br>
<br>
+ // numbers.<br>
<br>
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};<br>
<br>
+ v4f32_a = v4f32_a + 1;<br>
<br>
+ v4f32_a = v4f32_a + 0xFFFFFF;<br>
<br>
+ v4f32_a = v4f32_a + (-1567563LL); // expected-warning {{'long long' is incompatible with C++98}}<br>
<br>
+ v4f32_a = v4f32_a + (16777208);<br>
<br>
+ v4f32_a = v4f32_a + (16777219); // expected-error {{cannot convert between scalar type 'int' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}<br>
<br>
+}<br>
<br>
+<br>
<br>
+void floatTestConstantComparison(void);<br>
<br>
+void doubleTestConstantComparison(void);<br>
<br>
+<br>
<br>
+void floatTestConstantComparison(void) {<br>
<br>
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};<br>
<br>
+ v4i32 v4i32_r;<br>
<br>
+ v4i32_r = v4f32_a > 0.4f;<br>
<br>
+ v4i32_r = v4f32_a >= 0.4f;<br>
<br>
+ v4i32_r = v4f32_a < 0.4f;<br>
<br>
+ v4i32_r = v4f32_a <= 0.4f;<br>
<br>
+ v4i32_r = v4f32_a == 0.4f; // expected-warning {{comparing floating point with == or != is unsafe}}<br>
<br>
+ v4i32_r = v4f32_a != 0.4f; // expected-warning {{comparing floating point with == or != is unsafe}}<br>
<br>
+}<br>
<br>
+<br>
<br>
+void doubleTestConstantComparison(void) {<br>
<br>
+ v2f64 v2f64_a = {0.4, 0.4};<br>
<br>
+ v2i64 v2i64_r;<br>
<br>
+ v2i64_r = v2f64_a > 0.4;<br>
<br>
+ v2i64_r = v2f64_a >= 0.4;<br>
<br>
+ v2i64_r = v2f64_a < 0.4;<br>
<br>
+ v2i64_r = v2f64_a <= 0.4;<br>
<br>
+ v2i64_r = v2f64_a == 0.4; // expected-warning {{comparing floating point with == or != is unsafe}}<br>
<br>
+ v2i64_r = v2f64_a != 0.4; // expected-warning {{comparing floating point with == or != is unsafe}}<br>
<br>
+}<br>
<br>
+<br>
<br>
+void floatTestUnsignedType(unsigned char a, unsigned short b, unsigned int c,<br>
<br>
+ unsigned long long d) { // expected-warning {{'long long' is incompatible with C++98}}<br>
<br>
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};<br>
<br>
+ v4f64 v4f64_b = {0.4, 0.4, 0.4, 0.4};<br>
<br>
+<br>
<br>
+ v4f32_a = v4f32_a + a;<br>
<br>
+ v4f32_a = v4f32_a + b;<br>
<br>
+ v4f32_a = v4f32_a + c; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}<br>
<br>
+ v4f32_a = v4f32_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}<br>
<br>
+<br>
<br>
+ v4f64_b = v4f64_b + a;<br>
<br>
+ v4f64_b = v4f64_b + b;<br>
<br>
+ v4f64_b = v4f64_b + c;<br>
<br>
+ v4f64_b = v4f64_b + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v4f64' (vector of 4 'double' values) as implicit conversion would cause truncation}}<br>
<br>
+}<br>
<br>
+<br>
<br>
+void floatTestSignedType(char a, short b, int c, long long d) { // expected-warning {{'long long' is incompatible with C++98}}<br>
<br>
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};<br>
<br>
+ v4f64 v4f64_b = {0.4, 0.4, 0.4, 0.4};<br>
<br>
+<br>
<br>
+ v4f32_a = v4f32_a + a;<br>
<br>
+ v4f32_a = v4f32_a + b;<br>
<br>
+ v4f32_a = v4f32_a + c; // expected-error {{cannot convert between scalar type 'int' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}<br>
<br>
+ v4f32_a = v4f32_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}<br>
<br>
+<br>
<br>
+ v4f64_b = v4f64_b + a;<br>
<br>
+ v4f64_b = v4f64_b + b;<br>
<br>
+ v4f64_b = v4f64_b + c;<br>
<br>
+ v4f64_b = v4f64_b + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v4f64' (vector of 4 'double' values) as implicit conversion would cause truncation}}<br>
<br>
+}<br>
<br>
+<br>
<br>
+void intTestType(char a, short b, int c, long long d) { // expected-warning {{'long long' is incompatible with C++98}}<br>
<br>
+ v2i64 v2i64_a = {1, 2};<br>
<br>
+ v2i32 v2i32_a = {1, 2};<br>
<br>
+ v2i16 v2i16_a = {1, 2};<br>
<br>
+ v2i8 v2i8_a = {1, 2};<br>
<br>
+<br>
<br>
+ v2i64_a = v2i64_a + d;<br>
<br>
+ v2i64_a = v2i64_a + c;<br>
<br>
+ v2i64_a = v2i64_a + b;<br>
<br>
+ v2i64_a = v2i64_a + a;<br>
<br>
+<br>
<br>
+ v2i32_a = v2i32_a + d; // expected-warning {{implicit conversion loses integer precision: 'long long' to 'v2i32' (vector of 2 'int' values)}}<br>
<br>
+ v2i32_a = v2i32_a + c;<br>
<br>
+ v2i32_a = v2i32_a + b;<br>
<br>
+ v2i32_a = v2i32_a + a;<br>
<br>
+<br>
<br>
+ v2i16_a = v2i16_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v2i16' (vector of 2 'short' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2i16_a = v2i16_a + c; // expected-warning {{implicit conversion loses integer precision: 'int' to 'v2i16' (vector of 2 'short' values)}}<br>
<br>
+ v2i16_a = v2i16_a + b;<br>
<br>
+ v2i16_a = v2i16_a + a;<br>
<br>
+<br>
<br>
+ v2i8_a = v2i8_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2i8_a = v2i8_a + c; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2i8_a = v2i8_a + b; // expected-warning {{implicit conversion loses integer precision: 'short' to 'v2i8' (vector of 2 'char' values)}}<br>
<br>
+ v2i8_a = v2i8_a + a;<br>
<br>
+}<br>
<br>
+<br>
<br>
+void intTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,<br>
<br>
+ unsigned long long d) { // expected-warning {{'long long' is incompatible with C++98}}<br>
<br>
+ v2i64 v2i64_a = {1, 2};<br>
<br>
+ v2i32 v2i32_a = {1, 2};<br>
<br>
+ v2i16 v2i16_a = {1, 2};<br>
<br>
+ v2i8 v2i8_a = {1, 2};<br>
<br>
+<br>
<br>
+ v2i64_a = v2i64_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2i64' (vector of 2 'long long' values) as implicit conversion would cause truncation}}<br>
<br>
+<br>
<br>
+ v2i64_a = v2i64_a + c;<br>
<br>
+ v2i64_a = v2i64_a + b;<br>
<br>
+ v2i64_a = v2i64_a + a;<br>
<br>
+<br>
<br>
+ v2i32_a = v2i32_a + d; // expected-warning {{implicit conversion loses integer precision: 'unsigned long long' to 'v2i32' (vector of 2 'int' values)}}<br>
<br>
+ v2i32_a = v2i32_a + c; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2i32' (vector of 2 'int' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2i32_a = v2i32_a + b;<br>
<br>
+ v2i32_a = v2i32_a + a;<br>
<br>
+<br>
<br>
+ v2i16_a = v2i16_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2i16' (vector of 2 'short' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2i16_a = v2i16_a + c; // expected-warning {{implicit conversion loses integer precision: 'unsigned int' to 'v2i16' (vector of 2 'short' values)}}<br>
<br>
+ v2i16_a = v2i16_a + b; // expected-error {{cannot convert between scalar type 'unsigned short' and vector type 'v2i16' (vector of 2 'short' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2i16_a = v2i16_a + a;<br>
<br>
+<br>
<br>
+ v2i8_a = v2i8_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2i8_a = v2i8_a + c; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2i8_a = v2i8_a + b; // expected-warning {{implicit conversion loses integer precision: 'unsigned short' to 'v2i8' (vector of 2 'char' values)}}<br>
<br>
+ v2i8_a = v2i8_a + a; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}<br>
<br>
+}<br>
<br>
+<br>
<br>
+void uintTestType(char a, short b, int c, long long d) { // expected-warning {{'long long' is incompatible with C++98}}<br>
<br>
+ v2u64 v2u64_a = {1, 2};<br>
<br>
+ v2u32 v2u32_a = {1, 2};<br>
<br>
+ v2u16 v2u16_a = {1, 2};<br>
<br>
+ v2u8 v2u8_a = {1, 2};<br>
<br>
+<br>
<br>
+ v2u64_a = v2u64_a + d; // expected-warning {{implicit conversion changes signedness: 'long long' to 'v2u64' (vector of 2 'unsigned long long' values)}}<br>
<br>
+ v2u64_a = v2u64_a + c; // expected-warning {{implicit conversion changes signedness: 'int' to 'v2u64' (vector of 2 'unsigned long long' values)}}<br>
<br>
+ v2u64_a = v2u64_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u64' (vector of 2 'unsigned long long' values)}}<br>
<br>
+ v2u64_a = v2u64_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u64' (vector of 2 'unsigned long long' values)}}<br>
<br>
+<br>
<br>
+ v2u32_a = v2u32_a + d; // expected-warning {{implicit conversion loses integer precision: 'long long' to 'v2u32' (vector of 2 'unsigned int' values)}}<br>
<br>
+ v2u32_a = v2u32_a + c; // expected-warning {{implicit conversion changes signedness: 'int' to 'v2u32' (vector of 2 'unsigned int' values)}}<br>
<br>
+ v2u32_a = v2u32_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u32' (vector of 2 'unsigned int' values)}}<br>
<br>
+ v2u32_a = v2u32_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u32' (vector of 2 'unsigned int' values)}}<br>
<br>
+<br>
<br>
+ v2u16_a = v2u16_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v2u16' (vector of 2 'unsigned short' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2u16_a = v2u16_a + c; // expected-warning {{implicit conversion loses integer precision: 'int' to 'v2u16' (vector of 2 'unsigned short' values)}}<br>
<br>
+ v2u16_a = v2u16_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u16' (vector of 2 'unsigned short' values)}}<br>
<br>
+ v2u16_a = v2u16_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u16' (vector of 2 'unsigned short' values)}}<br>
<br>
+<br>
<br>
+ v2u8_a = v2u8_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2u8_a = v2u8_a + c; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2u8_a = v2u8_a + b; // expected-warning {{implicit conversion loses integer precision: 'short' to 'v2u8' (vector of 2 'unsigned char' values)}}<br>
<br>
+ v2u8_a = v2u8_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u8' (vector of 2 'unsigned char' values)}}<br>
<br>
+}<br>
<br>
+<br>
<br>
+void uintTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,<br>
<br>
+ unsigned long long d) { // expected-warning {{'long long' is incompatible with C++98}}<br>
<br>
+ v2u64 v2u64_a = {1, 2};<br>
<br>
+ v2u32 v2u32_a = {1, 2};<br>
<br>
+ v2u16 v2u16_a = {1, 2};<br>
<br>
+ v2u8 v2u8_a = {1, 2};<br>
<br>
+<br>
<br>
+ v2u64_a = v2u64_a + d;<br>
<br>
+ v2u64_a = v2u64_a + c;<br>
<br>
+ v2u64_a = v2u64_a + b;<br>
<br>
+ v2u64_a = v2u64_a + a;<br>
<br>
+<br>
<br>
+ v2u32_a = v2u32_a + d; // expected-warning {{implicit conversion loses integer precision: 'unsigned long long' to 'v2u32' (vector of 2 'unsigned int' values)}}<br>
<br>
+ v2u32_a = v2u32_a + c;<br>
<br>
+ v2u32_a = v2u32_a + b;<br>
<br>
+ v2u32_a = v2u32_a + a;<br>
<br>
+<br>
<br>
+ v2u16_a = v2u16_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2u16' (vector of 2 'unsigned short' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2u16_a = v2u16_a + c; // expected-warning {{implicit conversion loses integer precision: 'unsigned int' to 'v2u16' (vector of 2 'unsigned short' values)}}<br>
<br>
+ v2u16_a = v2u16_a + b;<br>
<br>
+ v2u16_a = v2u16_a + a;<br>
<br>
+<br>
<br>
+ v2u8_a = v2u8_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2u8_a = v2u8_a + c; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}<br>
<br>
+ v2u8_a = v2u8_a + b; // expected-warning {{implicit conversion loses integer precision: 'unsigned short' to 'v2u8' (vector of 2 'unsigned char' values)}}<br>
<br>
+ v2u8_a = v2u8_a + a;<br>
<br>
+}<br>
<br>
+<br>
<br>
+void uintTestConstant(v2u64 v2u64_a, v2u32 v2u32_a, v2u16 v2u16_a,<br>
<br>
+ v2u8 v2u8_a) {<br>
<br>
+ v2u64_a = v2u64_a + 0xFFFFFFFFFFFFFFFF;<br>
<br>
+ v2u32_a = v2u32_a + 0xFFFFFFFF;<br>
<br>
+ v2u16_a = v2u16_a + 0xFFFF;<br>
<br>
+ v2u8_a = v2u8_a + 0xFF;<br>
<br>
+<br>
<br>
+ v2u32_a = v2u32_a + 0x1FFFFFFFF; // expected-warning {{implicit conversion from 'long' to 'v2u32' (vector of 2 'unsigned int' values) changes value from 8589934591 to 4294967295}}<br>
<br>
+ v2u16_a = v2u16_a + 0x1FFFF; // expected-warning {{implicit conversion from 'int' to 'v2u16' (vector of 2 'unsigned short' values) changes value from 131071 to 65535}}<br>
<br>
+ v2u8_a = v2u8_a + 0x1FF; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}<br>
<br>
+}<br>
<br>
+<br>
<br>
+void intTestConstant(v2i64 v2i64_a, v2i32 v2i32_a, v2i16 v2i16_a, v2i8 v2i8_a) {<br>
<br>
+ // Legal upper bounds.<br>
<br>
+ v2i64_a = v2i64_a + static_cast<long long>(0x7FFFFFFFFFFFFFFF); // expected-warning {{'long long' is incompatible with C++98}}<br>
<br>
+ v2i32_a = v2i32_a + static_cast<int>(0x7FFFFFFF);<br>
<br>
+ v2i16_a = v2i16_a + static_cast<short>(0x7FFF);<br>
<br>
+ v2i8_a = v2i8_a + static_cast<char>(0x7F);<br>
<br>
+<br>
<br>
+ // Legal lower bounds.<br>
<br>
+ v2i64_a = v2i64_a + (-9223372036854775807);<br>
<br>
+ v2i32_a = v2i32_a +<br>
<a href="tel:(214)%20748-3648" value="+12147483648" target="_blank">(-2147483648</a>);<br>
<br>
+ v2i16_a = v2i16_a + (-32768);<br>
<br>
+ v2i8_a = v2i8_a + (-128);<br>
<br>
+<br>
<br>
+ // One increment/decrement more than the type can hold<br>
<br>
+ v2i32_a = v2i32_a +<br>
<a href="tel:(214)%20748-3648" value="+12147483648" target="_blank">2147483648</a>; // expected-warning {{implicit conversion from 'long' to 'v2i32' (vector of 2 'int' values) changes value from<br>
<a href="tel:(214)%20748-3648" value="+12147483648" target="_blank">2147483648</a> to -<a href="tel:(214)%20748-3648" value="+12147483648" target="_blank">2147483648</a>}}<br>
<br>
+ v2i16_a = v2i16_a + 32768; // expected-warning {{implicit conversion from 'int' to 'v2i16' (vector of 2 'short' values) changes value from 32768 to -32768}}<br>
<br>
+ v2i8_a = v2i8_a + 128; // expected-warning {{implicit conversion from 'int' to 'v2i8' (vector of 2 'char' values) changes value from 128 to -128}}<br>
<br>
+<br>
<br>
+ v2i32_a = v2i32_a +<br>
<a href="tel:(214)%20748-3649" value="+12147483649" target="_blank">(-2147483649</a>); // expected-warning {{implicit conversion from 'long' to 'v2i32' (vector of 2 'int' values) changes value from -2147483649 to 2147483647}}<br>
<br>
+ v2i16_a = v2i16_a + (-32769); // expected-warning {{implicit conversion from 'int' to 'v2i16' (vector of 2 'short' values) changes value from -32769 to 32767}}<br>
<br>
+ v2i8_a = v2i8_a + (-129); // expected-error {{cannot convert between scalar type 'int' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}<br>
<br>
+}<br>
<br>
<br>
<br>
Modified: cfe/trunk/test/Sema/vector-ops.c<br>
<br>
URL:<br>
<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vector-ops.c?rev=302935&r1=302934&r2=302935&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vector-ops.c?rev=302935&r1=302934&r2=302935&view=diff</a><br>
<br>
==============================================================================<br>
<br>
--- cfe/trunk/test/Sema/vector-ops.c (original)<br>
<br>
+++ cfe/trunk/test/Sema/vector-ops.c Fri May 12 14:11:06 2017<br>
<br>
@@ -13,11 +13,11 @@ void test1(v2u v2ua, v2s v2sa, v2f v2fa)<br>
<br>
(void)(~v2fa); // expected-error{{invalid argument type 'v2f' (vector of 2 'float' values) to unary}}<br>
<br>
<br>
<br>
// Comparison operators<br>
<br>
- 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)}}<br>
<br>
+ 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}}<br>
<br>
v2sa = (v2ua==v2sa);<br>
<br>
<br>
<br>
// Arrays<br>
<br>
- int array1[v2ua]; // expected-error{{size of array has non-integer type 'v2u' (vector of 2 'unsigned int' values)}}<br>
<br>
+ int array1[v2ua]; // expected-error{{size of array has non-integer type 'v2u' (vector of 2 'unsigned int' values}}<br>
<br>
int array2[17];<br>
<br>
// FIXME: error message below needs type!<br>
<br>
(void)(array2[v2ua]); // expected-error{{array subscript is not an integer}}<br>
<br>
@@ -28,108 +28,108 @@ void test1(v2u v2ua, v2s v2sa, v2f v2fa)<br>
<br>
}<br>
<br>
<br>
<br>
void testLogicalVecVec(v2u v2ua, v2s v2sa, v2f v2fa) {<br>
<br>
-<br>
<br>
// Logical operators<br>
<br>
- 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)}}<br>
<br>
- 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)}}<br>
<br>
+ v2ua = v2ua && v2ua; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2u'}}<br>
<br>
+ v2ua = v2ua || v2ua; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2u'}}<br>
<br>
<br>
<br>
- 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)}}<br>
<br>
- 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)}}<br>
<br>
+ v2ua = v2sa && v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}<br>
<br>
+ v2ua = v2sa || v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}<br>
<br>
<br>
<br>
- v2ua = v2ua && v2fa; // 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)}}<br>
<br>
- v2ua = v2ua || v2fa; // 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)}}<br>
<br>
+ v2ua = v2ua && v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}<br>
<br>
+ v2ua = v2ua || v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}<br>
<br>
<br>
<br>
- v2ua = v2sa && v2fa; // 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)}}<br>
<br>
- v2ua = v2sa || v2fa; // 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)}}<br>
<br>
+ v2ua = v2sa && v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}<br>
<br>
+ v2ua = v2sa || v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}<br>
<br>
<br>
<br>
- v2sa = v2sa && v2sa;<br>
<br>
- v2sa = v2sa || v2sa;<br>
<br>
+ v2sa = v2sa && v2sa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2s'}}<br>
<br>
+ v2sa = v2sa || v2sa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2s'}}<br>
<br>
<br>
<br>
- v2sa = v2ua && v2ua;<br>
<br>
- v2sa = v2ua || v2ua;<br>
<br>
+ v2sa = v2ua && v2ua; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2u'}}<br>
<br>
+ v2sa = v2ua || v2ua; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2u'}}<br>
<br>
<br>
<br>
- v2sa = v2sa && v2ua;<br>
<br>
- v2sa = v2sa || v2ua;<br>
<br>
+ v2sa = v2sa && v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}<br>
<br>
+ v2sa = v2sa || v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}<br>
<br>
<br>
<br>
- v2sa = v2sa && v2fa;<br>
<br>
- v2sa = v2sa || v2fa;<br>
<br>
+ v2sa = v2sa && v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}<br>
<br>
+ v2sa = v2sa || v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}<br>
<br>
<br>
<br>
- v2sa = v2ua && v2fa;<br>
<br>
- v2sa = v2ua || v2fa;<br>
<br>
+ v2sa = v2ua && v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}<br>
<br>
+ v2sa = v2ua || v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}<br>
<br>
<br>
<br>
- v2fa = v2fa && v2fa; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}<br>
<br>
- v2fa = v2fa || v2fa; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}<br>
<br>
+ v2fa = v2fa && v2fa; // expected-error {{logical expression with vector types 'v2f' (vector of 2 'float' values) and 'v2f'}}<br>
<br>
+ v2fa = v2fa || v2fa; // expected-error {{logical expression with vector types 'v2f' (vector of 2 'float' values) and 'v2f'}}<br>
<br>
<br>
<br>
- v2fa = v2sa && v2fa; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}<br>
<br>
- v2fa = v2sa || v2fa; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}<br>
<br>
+ v2fa = v2sa && v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}<br>
<br>
+ v2fa = v2sa || v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}<br>
<br>
<br>
<br>
- v2fa = v2ua && v2fa; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}<br>
<br>
- v2fa = v2ua || v2fa; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}<br>
<br>
+ v2fa = v2ua && v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}<br>
<br>
+ v2fa = v2ua || v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}<br>
<br>
<br>
<br>
- v2fa = v2ua && v2ua; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}<br>
<br>
- v2fa = v2ua || v2ua; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}<br>
<br>
+ v2fa = v2ua && v2ua; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2u'}}<br>
<br>
+ v2fa = v2ua || v2ua; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2u'}}<br>
<br>
<br>
<br>
- v2fa = v2sa && v2sa; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}<br>
<br>
- v2fa = v2sa || v2sa; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}<br>
<br>
+ v2fa = v2sa && v2sa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2s'}}<br>
<br>
+ v2fa = v2sa || v2sa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2s'}}<br>
<br>
<br>
<br>
- v2fa = v2sa && v2ua; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}<br>
<br>
- v2fa = v2sa || v2ua; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}<br>
<br>
+ v2fa = v2sa && v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}<br>
<br>
+ v2fa = v2sa || v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}<br>
<br>
}<br>
<br>
<br>
<br>
void testLogicalVecScalar(v2u v2ua, v2s v2sa, v2f v2fa) {<br>
<br>
-<br>
<br>
unsigned u1;<br>
<br>
- v2ua = v2ua && u1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values)<br>
and 'unsigned int')}}<br>
<br>
- v2ua = v2ua || u1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' v</blockquote></div>