r302935 - [Sema] Support implicit scalar to vector conversions
Simon Dardis via cfe-commits
cfe-commits at lists.llvm.org
Fri May 12 12:11:07 PDT 2017
Author: sdardis
Date: Fri May 12 14:11:06 2017
New Revision: 302935
URL: http://llvm.org/viewvc/llvm-project?rev=302935&view=rev
Log:
[Sema] Support implicit scalar to vector conversions
This patch teaches clang to perform implicit scalar to vector conversions
when one of the operands of a binary vector expression is a scalar which
can be converted to the element type of the vector without truncation
following GCC's implementation.
If the (constant) scalar is can be casted safely, it is implicitly casted to the
vector elements type and splatted to produce a vector of the same type.
Contributions from: Petar Jovanovic
Reviewers: bruno, vkalintiris
Differential Revision: https://reviews.llvm.org/D25866
Added:
cfe/trunk/test/Sema/vector-gcc-compat.c
cfe/trunk/test/Sema/vector-gcc-compat.cpp
Modified:
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-ops.c
cfe/trunk/test/Sema/zvector.c
cfe/trunk/test/SemaCXX/vector-no-lax.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=302935&r1=302934&r2=302935&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri May 12 14:11:06 2017
@@ -2465,6 +2465,9 @@ def err_attribute_invalid_size : Error<
"vector size not an integral multiple of component size">;
def err_attribute_zero_size : Error<"zero vector size">;
def err_attribute_size_too_large : Error<"vector size too large">;
+def err_typecheck_vector_not_convertable_implict_truncation : Error<
+ "cannot convert between %select{scalar|vector}0 type %1 and vector type"
+ " %2 as implicit conversion would cause truncation">;
def err_typecheck_vector_not_convertable : Error<
"cannot convert between vector values of different size (%0 and %1)">;
def err_typecheck_vector_not_convertable_non_scalar : Error<
@@ -5779,6 +5782,9 @@ def err_objc_object_assignment : Error<
"cannot assign to class object (%0 invalid)">;
def err_typecheck_invalid_operands : Error<
"invalid operands to binary expression (%0 and %1)">;
+def err_typecheck_logical_vector_expr_gnu_cpp_restrict : Error<
+ "logical expression with vector %select{type %1 and non-vector type %2|types"
+ " %1 and %2}0 is only supported in C++">;
def err_typecheck_sub_ptr_compatible : Error<
"%diff{$ and $ are not pointers to compatible types|"
"pointers to incompatible types}0,1">;
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=302935&r1=302934&r2=302935&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri May 12 14:11:06 2017
@@ -9285,6 +9285,8 @@ public:
/// type checking binary operators (subroutines of CreateBuiltinBinOp).
QualType InvalidOperands(SourceLocation Loc, ExprResult &LHS,
ExprResult &RHS);
+ QualType InvalidLogicalVectorOperands(SourceLocation Loc, ExprResult &LHS,
+ ExprResult &RHS);
QualType CheckPointerToMemberOperands( // C++ 5.5
ExprResult &LHS, ExprResult &RHS, ExprValueKind &VK,
SourceLocation OpLoc, bool isIndirect);
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=302935&r1=302934&r2=302935&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri May 12 14:11:06 2017
@@ -8031,6 +8031,33 @@ QualType Sema::InvalidOperands(SourceLoc
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 &LHS,
+ ExprResult &RHS) {
+ 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 @@ static bool tryVectorConvertAndSplat(Sem
return false;
}
+/// Test if a (constant) integer Int can be casted to another integer type
+/// IntTy without losing precision.
+static bool canConvertIntToOtherIntTy(Sema &S, 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 &S, 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 Float(S.Context.getFloatTypeSemantics(FloatTy));
+ Float.convertFromAPInt(Result, IntTy->hasSignedIntegerRepresentation(),
+ llvm::APFloat::rmTowardZero);
+ llvm::APSInt ConvertBack(S.Context.getIntWidth(IntTy),
+ !IntTy->hasSignedIntegerRepresentation());
+ bool Ignored = false;
+ Float.convertToInteger(ConvertBack, llvm::APFloat::rmNearestTiesToEven,
+ &Ignored);
+ if (Result != ConvertBack)
+ return true;
+ } else {
+ // Reject types that cannot be fully encoded into the mantissa of
+ // the float.
+ Bits = S.Context.getTypeSize(IntTy);
+ unsigned FloatPrec = llvm::APFloat::semanticsPrecision(
+ S.Context.getFloatTypeSemantics(FloatTy));
+ if (Bits > FloatPrec)
+ return true;
+ }
+
+ return false;
+}
+
+/// Attempt to convert and splat Scalar into a vector whose types matches
+/// Vector following GCC conversion rules. The rule is that implicit
+/// conversion can occur when Scalar can be casted to match Vector's element
+/// type without causing truncation of Scalar.
+static bool tryGCCVectorConvertAndSplat(Sema &S, ExprResult *Scalar,
+ ExprResult *Vector) {
+ QualType ScalarTy = Scalar->get()->getType().getUnqualifiedType();
+ QualType VectorTy = Vector->get()->getType().getUnqualifiedType();
+ const VectorType *VT = VectorTy->getAs<VectorType>();
+
+ assert(!isa<ExtVectorType>(VT) &&
+ "ExtVectorTypes should not be handled here!");
+
+ QualType VectorEltTy = VT->getElementType();
+
+ // Reject cases where the vector element type or the scalar element type are
+ // not integral or floating point types.
+ if (!VectorEltTy->isArithmeticType() || !ScalarTy->isArithmeticType())
+ return true;
+
+ // The conversion to apply to the scalar before splatting it,
+ // if necessary.
+ CastKind ScalarCast = CK_Invalid;
+
+ // Accept cases where the vector elements are integers and the scalar is
+ // an integer.
+ // FIXME: Notionally if the scalar was a floating point value with a precise
+ // integral representation, we could cast it to an appropriate integer
+ // type and then perform the rest of the checks here. GCC will perform
+ // this conversion in some cases as determined by the input language.
+ // We should accept it on a language independent basis.
+ if (VectorEltTy->isIntegralType(S.Context) &&
+ ScalarTy->isIntegralType(S.Context) &&
+ S.Context.getIntegerTypeOrder(VectorEltTy, ScalarTy)) {
+
+ if (canConvertIntToOtherIntTy(S, Scalar, VectorEltTy))
+ return true;
+
+ ScalarCast = CK_IntegralCast;
+ } else if (VectorEltTy->isRealFloatingType()) {
+ if (ScalarTy->isRealFloatingType()) {
+
+ // Reject cases where the scalar type is not a constant and has a higher
+ // Order than the vector element type.
+ llvm::APFloat Result(0.0);
+ bool CstScalar = Scalar->get()->EvaluateAsFloat(Result, S.Context);
+ int Order = S.Context.getFloatingTypeOrder(VectorEltTy, ScalarTy);
+ if (!CstScalar && Order < 0)
+ return true;
+
+ // If the scalar cannot be safely casted to the vector element type,
+ // reject it.
+ if (CstScalar) {
+ bool Truncated = false;
+ Result.convert(S.Context.getFloatTypeSemantics(VectorEltTy),
+ llvm::APFloat::rmNearestTiesToEven, &Truncated);
+ if (Truncated)
+ return true;
+ }
+
+ ScalarCast = CK_FloatingCast;
+ } else if (ScalarTy->isIntegralType(S.Context)) {
+ if (canConvertIntTyToFloatTy(S, Scalar, VectorEltTy))
+ return true;
+
+ ScalarCast = CK_IntegralToFloating;
+ } else
+ return true;
+ }
+
+ // Adjust scalar if desired.
+ if (Scalar) {
+ if (ScalarCast != CK_Invalid)
+ *Scalar = S.ImpCastExprToType(Scalar->get(), VectorEltTy, ScalarCast);
+ *Scalar = S.ImpCastExprToType(Scalar->get(), VectorTy, CK_VectorSplat);
+ }
+ return false;
+}
+
QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc, bool IsCompAssign,
bool AllowBothBool,
@@ -8146,19 +8329,29 @@ QualType Sema::CheckVectorOperands(ExprR
}
}
- // If there's an ext-vector type and a scalar, try to convert the scalar to
+ // If there's a vector type and a scalar, try to convert the scalar to
// the vector element type and splat.
- // FIXME: this should also work for regular vector types as supported in GCC.
- if (!RHSVecType && isa<ExtVectorType>(LHSVecType)) {
- if (!tryVectorConvertAndSplat(*this, &RHS, RHSType,
- LHSVecType->getElementType(), LHSType))
- return LHSType;
+ if (!RHSVecType) {
+ if (isa<ExtVectorType>(LHSVecType)) {
+ if (!tryVectorConvertAndSplat(*this, &RHS, RHSType,
+ LHSVecType->getElementType(), LHSType))
+ return LHSType;
+ } else {
+ if (!tryGCCVectorConvertAndSplat(*this, &RHS, &LHS))
+ return LHSType;
+ }
}
- if (!LHSVecType && isa<ExtVectorType>(RHSVecType)) {
- if (!tryVectorConvertAndSplat(*this, (IsCompAssign ? nullptr : &LHS),
- LHSType, RHSVecType->getElementType(),
- RHSType))
- return RHSType;
+ if (!LHSVecType) {
+ if (isa<ExtVectorType>(RHSVecType)) {
+ if (!tryVectorConvertAndSplat(*this, (IsCompAssign ? nullptr : &LHS),
+ LHSType, RHSVecType->getElementType(),
+ RHSType))
+ return RHSType;
+ } else {
+ if (LHS.get()->getValueKind() == VK_LValue ||
+ !tryGCCVectorConvertAndSplat(*this, &LHS, &RHS))
+ return RHSType;
+ }
}
// FIXME: The code below also handles conversion between vectors and
@@ -8211,6 +8404,22 @@ QualType Sema::CheckVectorOperands(ExprR
return QualType();
}
+
+ // If there is a vector type that is not a ExtVector and a scalar, we reach
+ // this point if scalar could not be converted to the vector's element type
+ // without truncation.
+ if ((RHSVecType && !isa<ExtVectorType>(RHSVecType)) ||
+ (LHSVecType && !isa<ExtVectorType>(LHSVecType))) {
+ QualType Scalar = LHSVecType ? RHSType : LHSType;
+ QualType Vector = LHSVecType ? LHSType : RHSType;
+ unsigned ScalarOrVector = LHSVecType && RHSVecType ? 1 : 0;
+ Diag(Loc,
+ diag::err_typecheck_vector_not_convertable_implict_truncation)
+ << ScalarOrVector << Scalar << Vector;
+
+ return QualType();
+ }
+
// Otherwise, use the generic diagnostic.
Diag(Loc, diag::err_typecheck_vector_not_convertable)
<< LHSType << RHSType
@@ -9830,6 +10039,12 @@ QualType Sema::CheckVectorLogicalOperand
if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion < 120 &&
vType->hasFloatingRepresentation())
return InvalidOperands(Loc, LHS, RHS);
+ // FIXME: The check for C++ here is for GCC compatibility. GCC rejects the
+ // usage of the logical operators && and || with vectors in C. This
+ // check could be notionally dropped.
+ if (!getLangOpts().CPlusPlus &&
+ !(isa<ExtVectorType>(vType->getAs<VectorType>())))
+ return InvalidLogicalVectorOperands(Loc, LHS, RHS);
return GetSignedVectorType(LHS.get()->getType());
}
@@ -11773,6 +11988,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(So
resultType = GetSignedVectorType(resultType);
break;
} else {
+ // FIXME: GCC's vector extension permits the usage of '!' with a vector
+ // type in C++. We should allow that here too.
return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
<< resultType << Input.get()->getSourceRange());
}
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=302935&r1=302934&r2=302935&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri May 12 14:11:06 2017
@@ -5356,6 +5356,15 @@ QualType Sema::CXXCheckConditionalOperan
// C++11 [expr.cond]p1
// The first expression is contextually converted to bool.
+ //
+ // FIXME; GCC's vector extension permits the use of a?b:c where the type of
+ // a is that of a integer vector with the same number of elements and
+ // size as the vectors of b and c. If one of either b or c is a scalar
+ // it is implicitly converted to match the type of the vector.
+ // Otherwise the expression is ill-formed. If both b and c are scalars,
+ // then b and c are checked and converted to the type of a if possible.
+ // Unlike the OpenCL ?: operator, the expression is evaluated as
+ // (a[0] != 0 ? b[0] : c[0], .. , a[n] != 0 ? b[n] : c[n]).
if (!Cond.get()->isTypeDependent()) {
ExprResult CondRes = CheckCXXBooleanCondition(Cond.get());
if (CondRes.isInvalid())
Modified: cfe/trunk/test/Sema/vector-cast.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vector-cast.c?rev=302935&r1=302934&r2=302935&view=diff
==============================================================================
--- cfe/trunk/test/Sema/vector-cast.c (original)
+++ cfe/trunk/test/Sema/vector-cast.c Fri May 12 14:11:06 2017
@@ -53,9 +53,8 @@ void f4() {
float2 f2;
double d, a, b, c;
float64x2_t v = {0.0, 1.0};
- // FIXME: These diagnostics are inaccurate: should complain that 'double' to vector 'float2' involves truncation
- f2 += d; // expected-error {{cannot convert between vector values of different size ('float2' (vector of 2 'float' values) and 'double')}}
- d += f2; // expected-error {{cannot convert between vector values of different size}}
+ 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}}
+ d += f2; // expected-error {{assigning to 'double' from incompatible type 'float2' (vector of 2 'float' values)}}
a = 3.0 + vget_low_f64(v);
b = vget_low_f64(v) + 3.0;
c = vget_low_f64(v);
Added: cfe/trunk/test/Sema/vector-gcc-compat.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vector-gcc-compat.c?rev=302935&view=auto
==============================================================================
--- cfe/trunk/test/Sema/vector-gcc-compat.c (added)
+++ cfe/trunk/test/Sema/vector-gcc-compat.c Fri May 12 14:11:06 2017
@@ -0,0 +1,330 @@
+// 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);
+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 v2i32_a, v2i16 v2i16_a, v2i8 v2i8_a);
+
+void arithmeticTest(void) {
+ v2i64 v2i64_a = (v2i64){0, 1};
+ v2i64 v2i64_r;
+
+ 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;
+}
+
+void comparisonTest(void) {
+ v2i64 v2i64_a = (v2i64){0, 1};
+ v2i64 v2i64_r;
+
+ 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 = 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_r = 1 >= v2i64_a;
+}
+
+void logicTest(void) {
+ v2i64 v2i64_a = (v2i64){0, 1};
+ v2i64 v2i64_b = (v2i64){2, 1};
+ v2i64 v2i64_c = (v2i64){3, 1};
+ v2i64 v2i64_r;
+
+ v2i64_r = !v2i64_a; // expected-error {{invalid argument type 'v2i64' (vector of 2 'long long' values) to unary expression}}
+ v2i64_r = ~v2i64_a;
+
+ 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}}
+
+ 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_a &= 1;
+ v2i64_a |= 1;
+ v2i64_a ^= 1;
+
+ 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++}}
+ 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++}}
+
+ 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++}}
+ 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++}}
+
+ v2i64_r = v2i64_a << 1;
+ v2i64_r = v2i64_a >> 1;
+
+ v2i64_r = 1 << v2i64_a;
+ v2i64_r = 1 >> v2i64_a;
+
+ v2i64_a <<= 1;
+ v2i64_a >>= 1;
+}
+
+// For operations with floating point types, we check that interger constants
+// can be respresented, or failing that checking based on the integer types.
+void floatTestConstant(void) {
+ // Test that constants added to floats must be expressible as floating point
+ // numbers.
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};
+ v4f32_a = v4f32_a + 1;
+ v4f32_a = v4f32_a + 0xFFFFFF;
+ v4f32_a = v4f32_a + (-1567563LL);
+ v4f32_a = v4f32_a + (16777208);
+ 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}}
+}
+
+void floatTestConstantComparison(void);
+void doubleTestConstantComparison(void);
+
+void floatTestConstantComparison(void) {
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};
+ v4i32 v4i32_r;
+ v4i32_r = v4f32_a > 0.4f;
+ v4i32_r = v4f32_a >= 0.4f;
+ v4i32_r = v4f32_a < 0.4f;
+ v4i32_r = v4f32_a <= 0.4f;
+ v4i32_r = v4f32_a == 0.4f; // expected-warning {{comparing floating point with == or != is unsafe}}
+ v4i32_r = v4f32_a != 0.4f; // expected-warning {{comparing floating point with == or != is unsafe}}
+}
+
+void doubleTestConstantComparison(void) {
+ v2f64 v2f64_a = {0.4, 0.4};
+ v2i64 v2i64_r;
+ v2i64_r = v2f64_a > 0.4;
+ v2i64_r = v2f64_a >= 0.4;
+ v2i64_r = v2f64_a < 0.4;
+ v2i64_r = v2f64_a <= 0.4;
+ v2i64_r = v2f64_a == 0.4; // expected-warning {{comparing floating point with == or != is unsafe}}
+ v2i64_r = v2f64_a != 0.4; // expected-warning {{comparing floating point with == or != is unsafe}}
+}
+
+void floatTestUnsignedType(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d) {
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};
+ v4f64 v4f64_b = {0.4, 0.4, 0.4, 0.4};
+
+ v4f32_a = v4f32_a + a;
+ v4f32_a = v4f32_a + b;
+ 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}}
+ 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}}
+
+ v4f64_b = v4f64_b + a;
+ v4f64_b = v4f64_b + b;
+ v4f64_b = v4f64_b + c;
+ 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}}
+}
+
+void floatTestSignedType(char a, short b, int c, long long d) {
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};
+ v4f64 v4f64_b = {0.4, 0.4, 0.4, 0.4};
+
+ v4f32_a = v4f32_a + a;
+ v4f32_a = v4f32_a + b;
+ 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}}
+ 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}}
+
+ v4f64_b = v4f64_b + a;
+ v4f64_b = v4f64_b + b;
+ v4f64_b = v4f64_b + c;
+ 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}}
+}
+
+void intTestType(char a, short b, int c, long long d) {
+ v2i64 v2i64_a = {1, 2};
+ v2i32 v2i32_a = {1, 2};
+ v2i16 v2i16_a = {1, 2};
+ v2i8 v2i8_a = {1, 2};
+
+ v2i64_a = v2i64_a + d;
+ v2i64_a = v2i64_a + c;
+ v2i64_a = v2i64_a + b;
+ v2i64_a = v2i64_a + a;
+
+ v2i32_a = v2i32_a + d; // expected-warning {{implicit conversion loses integer precision: 'long long' to 'v2i32' (vector of 2 'int' values)}}
+ v2i32_a = v2i32_a + c;
+ v2i32_a = v2i32_a + b;
+ v2i32_a = v2i32_a + a;
+
+ 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}}
+ v2i16_a = v2i16_a + c; // expected-warning {{implicit conversion loses integer precision: 'int' to 'v2i16' (vector of 2 'short' values)}}
+ v2i16_a = v2i16_a + b;
+ v2i16_a = v2i16_a + a;
+
+ 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}}
+ 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}}
+ v2i8_a = v2i8_a + b; // expected-warning {{implicit conversion loses integer precision: 'short' to 'v2i8' (vector of 2 'char' values)}}
+ v2i8_a = v2i8_a + a;
+}
+
+void intTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d) {
+ v2i64 v2i64_a = {1, 2};
+ v2i32 v2i32_a = {1, 2};
+ v2i16 v2i16_a = {1, 2};
+ v2i8 v2i8_a = {1, 2};
+
+ 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}}
+
+ v2i64_a = v2i64_a + c;
+ v2i64_a = v2i64_a + b;
+ v2i64_a = v2i64_a + a;
+
+ v2i32_a = v2i32_a + d; // expected-warning {{implicit conversion loses integer precision: 'unsigned long long' to 'v2i32' (vector of 2 'int' values)}}
+ 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}}
+ v2i32_a = v2i32_a + b;
+ v2i32_a = v2i32_a + a;
+
+ 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}}
+ v2i16_a = v2i16_a + c; // expected-warning {{implicit conversion loses integer precision: 'unsigned int' to 'v2i16' (vector of 2 'short' values)}}
+ 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}}
+ v2i16_a = v2i16_a + a;
+
+ 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}}
+ 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}}
+ v2i8_a = v2i8_a + b; // expected-warning {{implicit conversion loses integer precision: 'unsigned short' to 'v2i8' (vector of 2 'char' values)}}
+ 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}}
+}
+
+void uintTestType(char a, short b, int c, long long d) {
+ v2u64 v2u64_a = {1, 2};
+ v2u32 v2u32_a = {1, 2};
+ v2u16 v2u16_a = {1, 2};
+ v2u8 v2u8_a = {1, 2};
+
+ v2u64_a = v2u64_a + d; // expected-warning {{implicit conversion changes signedness: 'long long' to 'v2u64' (vector of 2 'unsigned long long' values)}}
+ v2u64_a = v2u64_a + c; // expected-warning {{implicit conversion changes signedness: 'int' to 'v2u64' (vector of 2 'unsigned long long' values)}}
+ v2u64_a = v2u64_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u64' (vector of 2 'unsigned long long' values)}}
+ v2u64_a = v2u64_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u64' (vector of 2 'unsigned long long' values)}}
+
+ v2u32_a = v2u32_a + d; // expected-warning {{implicit conversion loses integer precision: 'long long' to 'v2u32' (vector of 2 'unsigned int' values)}}
+ v2u32_a = v2u32_a + c; // expected-warning {{implicit conversion changes signedness: 'int' to 'v2u32' (vector of 2 'unsigned int' values)}}
+ v2u32_a = v2u32_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u32' (vector of 2 'unsigned int' values)}}
+ v2u32_a = v2u32_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u32' (vector of 2 'unsigned int' values)}}
+
+ 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}}
+ v2u16_a = v2u16_a + c; // expected-warning {{implicit conversion loses integer precision: 'int' to 'v2u16' (vector of 2 'unsigned short' values)}}
+ v2u16_a = v2u16_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u16' (vector of 2 'unsigned short' values)}}
+ v2u16_a = v2u16_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u16' (vector of 2 'unsigned short' values)}}
+
+ 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}}
+ 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}}
+ v2u8_a = v2u8_a + b; // expected-warning {{implicit conversion loses integer precision: 'short' to 'v2u8' (vector of 2 'unsigned char' values)}}
+ v2u8_a = v2u8_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u8' (vector of 2 'unsigned char' values)}}
+}
+
+void uintTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d) {
+ v2u64 v2u64_a = {1, 2};
+ v2u32 v2u32_a = {1, 2};
+ v2u16 v2u16_a = {1, 2};
+ v2u8 v2u8_a = {1, 2};
+
+ v2u64_a = v2u64_a + d;
+ v2u64_a = v2u64_a + c;
+ v2u64_a = v2u64_a + b;
+ v2u64_a = v2u64_a + a;
+
+ v2u32_a = v2u32_a + d; // expected-warning {{implicit conversion loses integer precision: 'unsigned long long' to 'v2u32' (vector of 2 'unsigned int' values)}}
+ v2u32_a = v2u32_a + c;
+ v2u32_a = v2u32_a + b;
+ v2u32_a = v2u32_a + a;
+
+ 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}}
+ v2u16_a = v2u16_a + c; // expected-warning {{implicit conversion loses integer precision: 'unsigned int' to 'v2u16' (vector of 2 'unsigned short' values)}}
+ v2u16_a = v2u16_a + b;
+ v2u16_a = v2u16_a + a;
+
+ 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}}
+ 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}}
+ v2u8_a = v2u8_a + b; // expected-warning {{implicit conversion loses integer precision: 'unsigned short' to 'v2u8' (vector of 2 'unsigned char' values)}}
+ v2u8_a = v2u8_a + a;
+}
+
+void uintTestConstant(v2u64 v2u64_a, v2u32 v2u32_a, v2u16 v2u16_a,
+ v2u8 v2u8_a) {
+ v2u64_a = v2u64_a + 0xFFFFFFFFFFFFFFFF;
+ v2u32_a = v2u32_a + 0xFFFFFFFF;
+ v2u16_a = v2u16_a + 0xFFFF;
+ v2u8_a = v2u8_a + 0xFF;
+
+ 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}}
+ 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}}
+ 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}}
+}
+
+void intTestConstant(v2i64 v2i64_a, v2i32 v2i32_a, v2i16 v2i16_a, v2i8 v2i8_a) {
+ // Legal upper bounds.
+ v2i64_a = v2i64_a + (long long)0x7FFFFFFFFFFFFFFF;
+ v2i32_a = v2i32_a + (int)0x7FFFFFFF;
+ v2i16_a = v2i16_a + (short)0x7FFF;
+ v2i8_a = v2i8_a + (char)0x7F;
+
+ // Legal lower bounds.
+ v2i64_a = v2i64_a + (-9223372036854775807);
+ v2i32_a = v2i32_a + (-2147483648);
+ v2i16_a = v2i16_a + (-32768);
+ v2i8_a = v2i8_a + (-128);
+
+ // One increment/decrement more than the type can hold
+ v2i32_a = v2i32_a + 2147483648; // expected-warning {{implicit conversion from 'long' to 'v2i32' (vector of 2 'int' values) changes value from 2147483648 to -2147483648}}
+ v2i16_a = v2i16_a + 32768; // expected-warning {{implicit conversion from 'int' to 'v2i16' (vector of 2 'short' values) changes value from 32768 to -32768}}
+ v2i8_a = v2i8_a + 128; // expected-warning {{implicit conversion from 'int' to 'v2i8' (vector of 2 'char' values) changes value from 128 to -128}}
+
+ v2i32_a = v2i32_a + (-2147483649); // expected-warning {{implicit conversion from 'long' to 'v2i32' (vector of 2 'int' values) changes value from -2147483649 to 2147483647}}
+ v2i16_a = v2i16_a + (-32769); // expected-warning {{implicit conversion from 'int' to 'v2i16' (vector of 2 'short' values) changes value from -32769 to 32767}}
+ 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}}
+}
Added: cfe/trunk/test/Sema/vector-gcc-compat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vector-gcc-compat.cpp?rev=302935&view=auto
==============================================================================
--- cfe/trunk/test/Sema/vector-gcc-compat.cpp (added)
+++ cfe/trunk/test/Sema/vector-gcc-compat.cpp Fri May 12 14:11:06 2017
@@ -0,0 +1,328 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything -std=c++11
+
+// Test the compatibility of clang++'s vector extensions with g++'s vector
+// extensions. In comparison to the extensions available in C, the !, ?:, && and
+// || operators work on vector types.
+
+typedef long long v2i64 __attribute__((vector_size(16))); // expected-warning {{'long long' is incompatible with C++98}}
+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))); // expected-warning {{'long long' is incompatible with C++98}}
+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); // expected-warning {{'long long' is incompatible with C++98}}
+void floatTestUnsignedType(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d); // expected-warning {{'long long' is incompatible with C++98}}
+void floatTestConstant(void);
+void intTestType(char a, short b, int c, long long d); // expected-warning {{'long long' is incompatible with C++98}}
+void intTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d); // expected-warning {{'long long' is incompatible with C++98}}
+void uintTestType(char a, short b, int c, long long d); // expected-warning {{'long long' is incompatible with C++98}}
+void uintTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d); // expected-warning {{'long long' is incompatible with C++98}}
+void uintTestConstant(v2u64 v2u64_a, v2u32 v2u32_a, v2u16 v2u16_a, v2u8 v2u8_a);
+void intTestConstant(v2i64 v2i64_a, v2i32 v2i32_a, v2i16 v2i16_a, v2i8 v2i8_a);
+
+void arithmeticTest(void) {
+ v2i64 v2i64_a = (v2i64){0, 1}; // expected-warning {{compound literals are a C99-specific feature}}
+ v2i64 v2i64_r;
+
+ 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;
+}
+
+void comparisonTest(void) {
+ v2i64 v2i64_a = (v2i64){0, 1}; // expected-warning {{compound literals are a C99-specific feature}}
+ v2i64 v2i64_r;
+
+ 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 = 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_r = 1 >= v2i64_a;
+}
+
+void logicTest(void) {
+ v2i64 v2i64_a = (v2i64){0, 1}; // expected-warning {{compound literals are a C99-specific feature}}
+ v2i64 v2i64_b = (v2i64){2, 1}; // expected-warning {{compound literals are a C99-specific feature}}
+ v2i64 v2i64_c = (v2i64){3, 1}; // expected-warning {{compound literals are a C99-specific feature}}
+ v2i64 v2i64_r;
+
+ v2i64_r = !v2i64_a; // expected-error {{invalid argument type 'v2i64' (vector of 2 'long long' values) to unary expression}}
+ v2i64_r = ~v2i64_a;
+
+ 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'}}
+
+ 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_a &= 1;
+ v2i64_a |= 1;
+ 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_a <<= 1;
+ v2i64_a >>= 1;
+}
+
+// For operations with floating point types, we check that interger constants
+// can be respresented, or failing that checking based on the integer types.
+void floatTestConstant(void) {
+ // Test that constants added to floats must be expressible as floating point
+ // numbers.
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};
+ v4f32_a = v4f32_a + 1;
+ v4f32_a = v4f32_a + 0xFFFFFF;
+ v4f32_a = v4f32_a + (-1567563LL); // expected-warning {{'long long' is incompatible with C++98}}
+ v4f32_a = v4f32_a + (16777208);
+ 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}}
+}
+
+void floatTestConstantComparison(void);
+void doubleTestConstantComparison(void);
+
+void floatTestConstantComparison(void) {
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};
+ v4i32 v4i32_r;
+ v4i32_r = v4f32_a > 0.4f;
+ v4i32_r = v4f32_a >= 0.4f;
+ v4i32_r = v4f32_a < 0.4f;
+ v4i32_r = v4f32_a <= 0.4f;
+ v4i32_r = v4f32_a == 0.4f; // expected-warning {{comparing floating point with == or != is unsafe}}
+ v4i32_r = v4f32_a != 0.4f; // expected-warning {{comparing floating point with == or != is unsafe}}
+}
+
+void doubleTestConstantComparison(void) {
+ v2f64 v2f64_a = {0.4, 0.4};
+ v2i64 v2i64_r;
+ v2i64_r = v2f64_a > 0.4;
+ v2i64_r = v2f64_a >= 0.4;
+ v2i64_r = v2f64_a < 0.4;
+ v2i64_r = v2f64_a <= 0.4;
+ v2i64_r = v2f64_a == 0.4; // expected-warning {{comparing floating point with == or != is unsafe}}
+ v2i64_r = v2f64_a != 0.4; // expected-warning {{comparing floating point with == or != is unsafe}}
+}
+
+void floatTestUnsignedType(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d) { // expected-warning {{'long long' is incompatible with C++98}}
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};
+ v4f64 v4f64_b = {0.4, 0.4, 0.4, 0.4};
+
+ v4f32_a = v4f32_a + a;
+ v4f32_a = v4f32_a + b;
+ 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}}
+ 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}}
+
+ v4f64_b = v4f64_b + a;
+ v4f64_b = v4f64_b + b;
+ v4f64_b = v4f64_b + c;
+ 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}}
+}
+
+void floatTestSignedType(char a, short b, int c, long long d) { // expected-warning {{'long long' is incompatible with C++98}}
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};
+ v4f64 v4f64_b = {0.4, 0.4, 0.4, 0.4};
+
+ v4f32_a = v4f32_a + a;
+ v4f32_a = v4f32_a + b;
+ 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}}
+ 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}}
+
+ v4f64_b = v4f64_b + a;
+ v4f64_b = v4f64_b + b;
+ v4f64_b = v4f64_b + c;
+ 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}}
+}
+
+void intTestType(char a, short b, int c, long long d) { // expected-warning {{'long long' is incompatible with C++98}}
+ v2i64 v2i64_a = {1, 2};
+ v2i32 v2i32_a = {1, 2};
+ v2i16 v2i16_a = {1, 2};
+ v2i8 v2i8_a = {1, 2};
+
+ v2i64_a = v2i64_a + d;
+ v2i64_a = v2i64_a + c;
+ v2i64_a = v2i64_a + b;
+ v2i64_a = v2i64_a + a;
+
+ v2i32_a = v2i32_a + d; // expected-warning {{implicit conversion loses integer precision: 'long long' to 'v2i32' (vector of 2 'int' values)}}
+ v2i32_a = v2i32_a + c;
+ v2i32_a = v2i32_a + b;
+ v2i32_a = v2i32_a + a;
+
+ 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}}
+ v2i16_a = v2i16_a + c; // expected-warning {{implicit conversion loses integer precision: 'int' to 'v2i16' (vector of 2 'short' values)}}
+ v2i16_a = v2i16_a + b;
+ v2i16_a = v2i16_a + a;
+
+ 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}}
+ 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}}
+ v2i8_a = v2i8_a + b; // expected-warning {{implicit conversion loses integer precision: 'short' to 'v2i8' (vector of 2 'char' values)}}
+ v2i8_a = v2i8_a + a;
+}
+
+void intTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d) { // expected-warning {{'long long' is incompatible with C++98}}
+ v2i64 v2i64_a = {1, 2};
+ v2i32 v2i32_a = {1, 2};
+ v2i16 v2i16_a = {1, 2};
+ v2i8 v2i8_a = {1, 2};
+
+ 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}}
+
+ v2i64_a = v2i64_a + c;
+ v2i64_a = v2i64_a + b;
+ v2i64_a = v2i64_a + a;
+
+ v2i32_a = v2i32_a + d; // expected-warning {{implicit conversion loses integer precision: 'unsigned long long' to 'v2i32' (vector of 2 'int' values)}}
+ 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}}
+ v2i32_a = v2i32_a + b;
+ v2i32_a = v2i32_a + a;
+
+ 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}}
+ v2i16_a = v2i16_a + c; // expected-warning {{implicit conversion loses integer precision: 'unsigned int' to 'v2i16' (vector of 2 'short' values)}}
+ 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}}
+ v2i16_a = v2i16_a + a;
+
+ 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}}
+ 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}}
+ v2i8_a = v2i8_a + b; // expected-warning {{implicit conversion loses integer precision: 'unsigned short' to 'v2i8' (vector of 2 'char' values)}}
+ 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}}
+}
+
+void uintTestType(char a, short b, int c, long long d) { // expected-warning {{'long long' is incompatible with C++98}}
+ v2u64 v2u64_a = {1, 2};
+ v2u32 v2u32_a = {1, 2};
+ v2u16 v2u16_a = {1, 2};
+ v2u8 v2u8_a = {1, 2};
+
+ v2u64_a = v2u64_a + d; // expected-warning {{implicit conversion changes signedness: 'long long' to 'v2u64' (vector of 2 'unsigned long long' values)}}
+ v2u64_a = v2u64_a + c; // expected-warning {{implicit conversion changes signedness: 'int' to 'v2u64' (vector of 2 'unsigned long long' values)}}
+ v2u64_a = v2u64_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u64' (vector of 2 'unsigned long long' values)}}
+ v2u64_a = v2u64_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u64' (vector of 2 'unsigned long long' values)}}
+
+ v2u32_a = v2u32_a + d; // expected-warning {{implicit conversion loses integer precision: 'long long' to 'v2u32' (vector of 2 'unsigned int' values)}}
+ v2u32_a = v2u32_a + c; // expected-warning {{implicit conversion changes signedness: 'int' to 'v2u32' (vector of 2 'unsigned int' values)}}
+ v2u32_a = v2u32_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u32' (vector of 2 'unsigned int' values)}}
+ v2u32_a = v2u32_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u32' (vector of 2 'unsigned int' values)}}
+
+ 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}}
+ v2u16_a = v2u16_a + c; // expected-warning {{implicit conversion loses integer precision: 'int' to 'v2u16' (vector of 2 'unsigned short' values)}}
+ v2u16_a = v2u16_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u16' (vector of 2 'unsigned short' values)}}
+ v2u16_a = v2u16_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u16' (vector of 2 'unsigned short' values)}}
+
+ 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}}
+ 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}}
+ v2u8_a = v2u8_a + b; // expected-warning {{implicit conversion loses integer precision: 'short' to 'v2u8' (vector of 2 'unsigned char' values)}}
+ v2u8_a = v2u8_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u8' (vector of 2 'unsigned char' values)}}
+}
+
+void uintTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d) { // expected-warning {{'long long' is incompatible with C++98}}
+ v2u64 v2u64_a = {1, 2};
+ v2u32 v2u32_a = {1, 2};
+ v2u16 v2u16_a = {1, 2};
+ v2u8 v2u8_a = {1, 2};
+
+ v2u64_a = v2u64_a + d;
+ v2u64_a = v2u64_a + c;
+ v2u64_a = v2u64_a + b;
+ v2u64_a = v2u64_a + a;
+
+ v2u32_a = v2u32_a + d; // expected-warning {{implicit conversion loses integer precision: 'unsigned long long' to 'v2u32' (vector of 2 'unsigned int' values)}}
+ v2u32_a = v2u32_a + c;
+ v2u32_a = v2u32_a + b;
+ v2u32_a = v2u32_a + a;
+
+ 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}}
+ v2u16_a = v2u16_a + c; // expected-warning {{implicit conversion loses integer precision: 'unsigned int' to 'v2u16' (vector of 2 'unsigned short' values)}}
+ v2u16_a = v2u16_a + b;
+ v2u16_a = v2u16_a + a;
+
+ 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}}
+ 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}}
+ v2u8_a = v2u8_a + b; // expected-warning {{implicit conversion loses integer precision: 'unsigned short' to 'v2u8' (vector of 2 'unsigned char' values)}}
+ v2u8_a = v2u8_a + a;
+}
+
+void uintTestConstant(v2u64 v2u64_a, v2u32 v2u32_a, v2u16 v2u16_a,
+ v2u8 v2u8_a) {
+ v2u64_a = v2u64_a + 0xFFFFFFFFFFFFFFFF;
+ v2u32_a = v2u32_a + 0xFFFFFFFF;
+ v2u16_a = v2u16_a + 0xFFFF;
+ v2u8_a = v2u8_a + 0xFF;
+
+ 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}}
+ 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}}
+ 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}}
+}
+
+void intTestConstant(v2i64 v2i64_a, v2i32 v2i32_a, v2i16 v2i16_a, v2i8 v2i8_a) {
+ // Legal upper bounds.
+ v2i64_a = v2i64_a + static_cast<long long>(0x7FFFFFFFFFFFFFFF); // expected-warning {{'long long' is incompatible with C++98}}
+ v2i32_a = v2i32_a + static_cast<int>(0x7FFFFFFF);
+ v2i16_a = v2i16_a + static_cast<short>(0x7FFF);
+ v2i8_a = v2i8_a + static_cast<char>(0x7F);
+
+ // Legal lower bounds.
+ v2i64_a = v2i64_a + (-9223372036854775807);
+ v2i32_a = v2i32_a + (-2147483648);
+ v2i16_a = v2i16_a + (-32768);
+ v2i8_a = v2i8_a + (-128);
+
+ // One increment/decrement more than the type can hold
+ v2i32_a = v2i32_a + 2147483648; // expected-warning {{implicit conversion from 'long' to 'v2i32' (vector of 2 'int' values) changes value from 2147483648 to -2147483648}}
+ v2i16_a = v2i16_a + 32768; // expected-warning {{implicit conversion from 'int' to 'v2i16' (vector of 2 'short' values) changes value from 32768 to -32768}}
+ v2i8_a = v2i8_a + 128; // expected-warning {{implicit conversion from 'int' to 'v2i8' (vector of 2 'char' values) changes value from 128 to -128}}
+
+ v2i32_a = v2i32_a + (-2147483649); // expected-warning {{implicit conversion from 'long' to 'v2i32' (vector of 2 'int' values) changes value from -2147483649 to 2147483647}}
+ v2i16_a = v2i16_a + (-32769); // expected-warning {{implicit conversion from 'int' to 'v2i16' (vector of 2 'short' values) changes value from -32769 to 32767}}
+ 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}}
+}
Modified: cfe/trunk/test/Sema/vector-ops.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vector-ops.c?rev=302935&r1=302934&r2=302935&view=diff
==============================================================================
--- cfe/trunk/test/Sema/vector-ops.c (original)
+++ cfe/trunk/test/Sema/vector-ops.c Fri May 12 14:11:06 2017
@@ -13,11 +13,11 @@ void test1(v2u v2ua, v2s v2sa, v2f v2fa)
(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 test1(v2u v2ua, v2s v2sa, v2f v2fa)
}
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 {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2u'}}
+ v2ua = v2ua || v2ua; // expected-error {{logical expression with vector types '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 '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
+ v2ua = v2sa && v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}
+ v2ua = v2sa || v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}
- 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)}}
- 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)}}
+ v2ua = v2ua && v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}
+ v2ua = v2ua || v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}
- 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)}}
- 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)}}
+ v2ua = v2sa && v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}
+ v2ua = v2sa || v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}
- v2sa = v2sa && v2sa;
- v2sa = v2sa || v2sa;
+ v2sa = v2sa && v2sa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2s'}}
+ v2sa = v2sa || v2sa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2s'}}
- v2sa = v2ua && v2ua;
- v2sa = v2ua || v2ua;
+ v2sa = v2ua && v2ua; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2u'}}
+ v2sa = v2ua || v2ua; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2u'}}
- v2sa = v2sa && v2ua;
- v2sa = v2sa || v2ua;
+ v2sa = v2sa && v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}
+ v2sa = v2sa || v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}
- v2sa = v2sa && v2fa;
- v2sa = v2sa || v2fa;
+ v2sa = v2sa && v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}
+ v2sa = v2sa || v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}
- v2sa = v2ua && v2fa;
- v2sa = v2ua || v2fa;
+ v2sa = v2ua && v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}
+ v2sa = v2ua || v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}
- 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)}}
- 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)}}
+ v2fa = v2fa && v2fa; // expected-error {{logical expression with vector types 'v2f' (vector of 2 'float' values) and 'v2f'}}
+ v2fa = v2fa || v2fa; // expected-error {{logical expression with vector types 'v2f' (vector of 2 'float' values) and 'v2f'}}
- 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)}}
- 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)}}
+ v2fa = v2sa && v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}
+ v2fa = v2sa || v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}
- 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)}}
- 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)}}
+ v2fa = v2ua && v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}
+ v2fa = v2ua || v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}
- 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)}}
- 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)}}
+ v2fa = v2ua && v2ua; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2u'}}
+ v2fa = v2ua || v2ua; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2u'}}
- 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)}}
- 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)}}
+ v2fa = v2sa && v2sa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2s'}}
+ v2fa = v2sa || v2sa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2s'}}
- 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)}}
- 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)}}
+ v2fa = v2sa && v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}
+ v2fa = v2sa || v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}
}
void testLogicalVecScalar(v2u v2ua, v2s v2sa, v2f v2fa) {
-
unsigned u1;
- 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) and 'unsigned int')}}
- 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) and 'unsigned int')}}
+ v2ua = v2ua && u1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'unsigned int' is only supported in C++}}
+ v2ua = v2ua || u1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'unsigned int' is only supported in C++}}
- v2sa = v2sa && u1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}}
- v2sa = v2sa || u1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}}
+ v2sa = v2sa && u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2s' (vector of 2 'int' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}}
+ v2sa = v2sa || u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2s' (vector of 2 'int' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}}
- v2ua = v2sa && u1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}}
- v2ua = v2sa || u1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}}
- v2sa = 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) and 'unsigned int')}}
- v2sa = 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) and 'unsigned int')}}
+ v2ua = v2sa && u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2s' (vector of 2 'int' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}}
+ v2ua = v2sa || u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2s' (vector of 2 'int' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}}
+ v2sa = v2ua && u1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'unsigned int' is only supported in C++}}
+ v2sa = v2ua || u1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'unsigned int' is only supported in C++}}
- v2ua = v2fa && u1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}}
- v2ua = v2fa || u1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}}
+ v2ua = v2fa && u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}}
+ v2ua = v2fa || u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}}
- v2sa = v2fa && u1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}}
- v2sa = v2fa || u1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}}
+ v2sa = v2fa && u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}}
+ v2sa = v2fa || u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}}
int s1;
- v2ua = v2ua && s1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'int')}}
- v2ua = v2ua || s1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'int')}}
+ v2ua = v2ua && s1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'int' is only supported in C++}}
+ v2ua = v2ua || s1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'int' is only supported in C++}}
- v2sa = v2sa && s1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'int')}}
- v2sa = v2sa || s1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'int')}}
+ v2sa = v2sa && s1; // expected-error {{logical expression with vector type 'v2s' (vector of 2 'int' values) and non-vector type 'int' is only supported in C++}}
+ v2sa = v2sa || s1; // expected-error {{logical expression with vector type 'v2s' (vector of 2 'int' values) and non-vector type 'int' is only supported in C++}}
- v2ua = v2sa && s1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'int')}}
- v2ua = v2sa || s1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'int')}}
- v2sa = v2ua && s1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'int')}}
- v2sa = v2ua || s1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'int')}}
+ v2ua = v2sa && s1; // expected-error {{logical expression with vector type 'v2s' (vector of 2 'int' values) and non-vector type 'int' is only supported in C++}}
+ v2ua = v2sa || s1; // expected-error {{logical expression with vector type 'v2s' (vector of 2 'int' values) and non-vector type 'int' is only supported in C++}}
- v2ua = v2fa && s1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int')}}
- v2ua = v2fa || s1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int')}}
+ v2sa = v2ua && s1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'int' is only supported in C++}}
+ v2sa = v2ua || s1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'int' is only supported in C++}}
- v2sa = v2fa && s1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int')}}
- v2sa = v2fa || s1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int')}}
+ v2ua = v2fa && s1; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int'}}
+ v2ua = v2fa || s1; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int'}}
+
+ v2sa = v2fa && s1; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int'}}
+ v2sa = v2fa || s1; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int'}}
float f1;
- v2ua = v2ua && f1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'float')}}
- v2ua = v2ua || f1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'float')}}
+ v2ua = v2ua && f1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'float' is only supported in C++}}
+ v2ua = v2ua || f1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'float' is only supported in C++}}
+
+ v2sa = v2sa && f1; // expected-error {{logical expression with vector type 'v2s' (vector of 2 'int' values) and non-vector type 'float' is only supported in C++}}
+ v2sa = v2sa || f1; // expected-error {{logical expression with vector type 'v2s' (vector of 2 'int' values) and non-vector type 'float' is only supported in C++}}
- v2sa = v2sa && f1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'float')}}
- v2sa = v2sa || f1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'float')}}
+ v2ua = v2sa && f1; // expected-error {{logical expression with vector type 'v2s' (vector of 2 'int' values) and non-vector type 'float' is only supported in C++}}
+ v2ua = v2sa || f1; // expected-error {{logical expression with vector type 'v2s' (vector of 2 'int' values) and non-vector type 'float' is only supported in C++}}
- v2ua = v2sa && f1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'float')}}
- v2ua = v2sa || f1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'float')}}
- v2sa = v2ua && f1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'float')}}
- v2sa = v2ua || f1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'float')}}
+ v2sa = v2ua && f1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'float' is only supported in C++}}
+ v2sa = v2ua || f1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'float' is only supported in C++}}
- v2ua = v2fa && f1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'float')}}
- v2ua = v2fa || f1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'float')}}
+ v2ua = v2fa && f1; // expected-error {{logical expression with vector type 'v2f' (vector of 2 'float' values) and non-vector type 'float' is only supported in C++}}
+ v2ua = v2fa || f1; // expected-error {{logical expression with vector type 'v2f' (vector of 2 'float' values) and non-vector type 'float' is only supported in C++}}
- v2sa = v2fa && f1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'float')}}
- v2sa = v2fa || f1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'float')}}
+ v2sa = v2fa && f1; // expected-error {{logical expression with vector type 'v2f' (vector of 2 'float' values) and non-vector type 'float' is only supported in C++}}
+ v2sa = v2fa || f1; // expected-error {{logical expression with vector type 'v2f' (vector of 2 'float' values) and non-vector type 'float' is only supported in C++}}
}
Modified: cfe/trunk/test/Sema/zvector.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/zvector.c?rev=302935&r1=302934&r2=302935&view=diff
==============================================================================
--- cfe/trunk/test/Sema/zvector.c (original)
+++ cfe/trunk/test/Sema/zvector.c Fri May 12 14:11:06 2017
@@ -326,14 +326,14 @@ void foo(void)
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 @@ void foo(void)
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;
Modified: cfe/trunk/test/SemaCXX/vector-no-lax.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/vector-no-lax.cpp?rev=302935&r1=302934&r2=302935&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/vector-no-lax.cpp (original)
+++ cfe/trunk/test/SemaCXX/vector-no-lax.cpp Fri May 12 14:11:06 2017
@@ -4,6 +4,6 @@ typedef int __attribute__((vector_size (
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;
}
More information about the cfe-commits
mailing list