Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -9284,7 +9284,7 @@ QualType CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign, bool AllowBothBool, bool AllowBoolConversion); - QualType GetSignedVectorType(QualType V); + QualType GetSignedVectorType(QualType V, bool WantExtVectorType); QualType CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool isRelational); QualType CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS, Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -9711,24 +9711,45 @@ return InvalidOperands(Loc, LHS, RHS); } - -// Return a signed type that is of identical size and number of elements. -// For floating point vectors, return an integer type of identical size -// and number of elements. -QualType Sema::GetSignedVectorType(QualType V) { +// Return a signed ext_vector type that is of identical size and number of +// elements. For floating point vectors, return an integer type of identical +// size and number of elements. In the non ext_vector case, search from the +// largest to the smallest to avoid cases where long long == long, where long +// gets picked over long long. +QualType Sema::GetSignedVectorType(QualType V, bool WantExtVector) { const VectorType *VTy = V->getAs(); unsigned TypeSize = Context.getTypeSize(VTy->getElementType()); - if (TypeSize == Context.getTypeSize(Context.CharTy)) - return Context.getExtVectorType(Context.CharTy, VTy->getNumElements()); - else if (TypeSize == Context.getTypeSize(Context.ShortTy)) - return Context.getExtVectorType(Context.ShortTy, VTy->getNumElements()); - else if (TypeSize == Context.getTypeSize(Context.IntTy)) - return Context.getExtVectorType(Context.IntTy, VTy->getNumElements()); + + if (WantExtVector) { + if (TypeSize == Context.getTypeSize(Context.CharTy)) + return Context.getExtVectorType(Context.CharTy, VTy->getNumElements()); + else if (TypeSize == Context.getTypeSize(Context.ShortTy)) + return Context.getExtVectorType(Context.ShortTy, VTy->getNumElements()); + else if (TypeSize == Context.getTypeSize(Context.IntTy)) + return Context.getExtVectorType(Context.IntTy, VTy->getNumElements()); + else if (TypeSize == Context.getTypeSize(Context.LongTy)) + return Context.getExtVectorType(Context.LongTy, VTy->getNumElements()); + assert(TypeSize == Context.getTypeSize(Context.LongLongTy) && + "Unhandled vector element size in vector compare"); + return Context.getExtVectorType(Context.LongLongTy, VTy->getNumElements()); + } + + if (TypeSize == Context.getTypeSize(Context.LongLongTy)) + return Context.getVectorType(Context.LongLongTy, VTy->getNumElements(), + VectorType::GenericVector); else if (TypeSize == Context.getTypeSize(Context.LongTy)) - return Context.getExtVectorType(Context.LongTy, VTy->getNumElements()); - assert(TypeSize == Context.getTypeSize(Context.LongLongTy) && + return Context.getVectorType(Context.LongTy, VTy->getNumElements(), + VectorType::GenericVector); + else if (TypeSize == Context.getTypeSize(Context.IntTy)) + return Context.getVectorType(Context.IntTy, VTy->getNumElements(), + VectorType::GenericVector); + else if (TypeSize == Context.getTypeSize(Context.ShortTy)) + return Context.getVectorType(Context.ShortTy, VTy->getNumElements(), + VectorType::GenericVector); + assert(TypeSize == Context.getTypeSize(Context.CharTy) && "Unhandled vector element size in vector compare"); - return Context.getExtVectorType(Context.LongLongTy, VTy->getNumElements()); + return Context.getVectorType(Context.CharTy, VTy->getNumElements(), + VectorType::GenericVector); } /// CheckVectorCompareOperands - vector comparisons are a clang extension that @@ -9747,6 +9768,8 @@ return vType; QualType LHSType = LHS.get()->getType(); + bool isExtVectorType = + isa(vType->getAs()) || getLangOpts().OpenCL; // If AltiVec, the comparison results in a numeric type, i.e. // bool for C++, int for C @@ -9775,9 +9798,9 @@ assert (RHS.get()->getType()->hasFloatingRepresentation()); CheckFloatComparison(Loc, LHS.get(), RHS.get()); } - + // Return a signed type for the vector. - return GetSignedVectorType(vType); + return GetSignedVectorType(vType, isExtVectorType); } QualType Sema::CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS, @@ -9792,8 +9815,10 @@ if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion < 120 && vType->hasFloatingRepresentation()) return InvalidOperands(Loc, LHS, RHS); - - return GetSignedVectorType(LHS.get()->getType()); + bool isExtVectorType = + isa(vType->getAs()) || getLangOpts().OpenCL; + + return GetSignedVectorType(LHS.get()->getType(), isExtVectorType); } inline QualType Sema::CheckBitwiseOperands(ExprResult &LHS, ExprResult &RHS, @@ -11732,7 +11757,7 @@ << resultType << Input.get()->getSourceRange()); } // Vector logical not returns the signed variant of the operand type. - resultType = GetSignedVectorType(resultType); + resultType = GetSignedVectorType(resultType, true); break; } else { return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) Index: test/Sema/vector-ops.c =================================================================== --- test/Sema/vector-ops.c +++ test/Sema/vector-ops.c @@ -13,7 +13,7 @@ (void)(~v2fa); // expected-error{{invalid argument type 'v2f' (vector of 2 'float' values) to unary}} // Comparison operators - v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from 'int __attribute__((ext_vector_type(2)))' (vector of 2 'int' values)}} + v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}} v2sa = (v2ua==v2sa); // Arrays