r302935 - [Sema] Support implicit scalar to vector conversions

Vitaly Buka via cfe-commits cfe-commits at lists.llvm.org
Mon May 15 15:21:56 PDT 2017


fixed with r303121.
I didn't change logic, but please double check that getting there without
assigning cast was expected.

On Mon, May 15, 2017 at 1:03 PM Vitaly Buka <vitalybuka at google.com> wrote:

> Then I'll take a look, and if it's not something trivial I'll revert it.
>
> On Mon, May 15, 2017 at 1:00 PM Simon Dardis <Simon.Dardis at imgtec.com>
> wrote:
>
>>
>> Thanks, I'll try and look at this tomorrow.
>>
>> Simon
>>
>>
>>
>> From: Vitaly Buka [vitalybuka at google.com]
>>
>> Sent: 15 May 2017 20:57
>>
>> To: Simon Dardis; cfe-commits at lists.llvm.org
>>
>> Subject: Re: r302935 - [Sema] Support implicit scalar to vector
>> conversions
>>
>>
>> From ubsan bot:
>>
>>
>> http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/4892/steps/check-clang%20ubsan/logs/stdio
>>
>> 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'
>>     #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
>>     #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
>>     #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
>>     #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
>>
>>
>>
>> On Fri, May 12, 2017 at 12:24 PM Simon Dardis via cfe-commits <
>> cfe-commits at lists.llvm.org> wrote:
>>
>>
>>
>> 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 <(214)%20748-3648>);
>>
>> +  v2i16_a = v2i16_a + (-32768);
>>
>> +  v2i8_a = v2i8_a + (-128);
>>
>> +
>>
>> +  // One increment/decrement more than the type can hold
>>
>> +  v2i32_a = v2i32_a +
>> 2147483648 <(214)%20748-3648>; // expected-warning {{implicit conversion
>> from 'long' to 'v2i32' (vector of 2 'int' values) changes value from
>> 2147483648 <(214)%20748-3648> to -2147483648 <(214)%20748-3648>}}
>>
>> +  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 <(214)%20748-3649>); // expected-warning {{implicit
>> conversion from 'long' to 'v2i32' (vector of 2 'int' values) changes value
>> from -2147483649 <(214)%20748-3649> to
>> 2147483647 <(214)%20748-3647>}}
>>
>> +  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 <(214)%20748-3648>);
>>
>> +  v2i16_a = v2i16_a + (-32768);
>>
>> +  v2i8_a = v2i8_a + (-128);
>>
>> +
>>
>> +  // One increment/decrement more than the type can hold
>>
>> +  v2i32_a = v2i32_a +
>> 2147483648 <(214)%20748-3648>; // expected-warning {{implicit conversion
>> from 'long' to 'v2i32' (vector of 2 'int' values) changes value from
>> 2147483648 <(214)%20748-3648> to -2147483648 <(214)%20748-3648>}}
>>
>> +  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 <(214)%20748-3649>); // expected-warning {{implicit
>> conversion from 'long' to 'v2i32' (vector of 2 'int' values) changes value
>> from -2147483649 <(214)%20748-3649> to 2147483647 <(214)%20748-3647>}}
>>
>> +  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' v
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170515/2c36704f/attachment-0001.html>


More information about the cfe-commits mailing list