vbyakovlcl created this revision. vbyakovlcl added reviewers: ahatanak, aaron.ballman. vbyakovlcl added subscribers: andreybokhanko, cfe-commits. vbyakovlcl set the repository for this revision to rL LLVM. vbyakovlcl changed the visibility of this Differential Revision from "Public (No Login Required)" to "All Users". Herald added a subscriber: aemerson.
This fixes an error and gcc incompatibilities in vector shifts reported by Akira Hatanaka -------------------------------------------------------------------------- From: Akira Hatanaka <ahata...@gmail.com> Date: Fri, Sep 2, 2016 at 3:00 AM Subject: Re: [PATCH] D21678: Fix For pr28288 - Error message in shift of vector values To: vladimi...@gmail.com, ulrich.weig...@de.ibm.com, amjad.ab...@intel.com, guy.ben...@intel.com, aaron.ball...@gmail.com Cc: ahata...@gmail.com, andreybokha...@gmail.com, anastasia.stul...@arm.com, dmitry.poluk...@gmail.com, cfe-commits@lists.llvm.org ahatanak added a subscriber: ahatanak. ahatanak added a comment. This patch causes clang to error out on the following code, which used to compile fine: $ cat f2.c typedef __attribute__((__ext_vector_type__(8))) unsigned short vector_ushort8; vector_ushort8 foo1(void) { return 1 << (vector_ushort8){7,6,5,4,3,2,1,0}; } $ clang f2.c -c clang used to transform the scaler operand to a vector operand (similar to the way gcc's vector is handled) when compiling for normal c/c++ (but printed an error message when compiling for opencl), but this patch dropped the check for LangOpts added in r230464 and changed that behavior. I don't think this was intentional? Repository: rL LLVM https://reviews.llvm.org/D21678 Repository: rL LLVM https://reviews.llvm.org/D24467 Files: llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td llvm/tools/clang/lib/Sema/SemaExpr.cpp llvm/tools/clang/test/Sema/vecshift.c
Index: llvm/tools/clang/lib/Sema/SemaExpr.cpp =================================================================== --- llvm/tools/clang/lib/Sema/SemaExpr.cpp +++ llvm/tools/clang/lib/Sema/SemaExpr.cpp @@ -8721,24 +8721,28 @@ static QualType checkVectorShift(Sema &S, ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign) { // OpenCL v1.1 s6.3.j says RHS can be a vector only if LHS is a vector. - if (!LHS.get()->getType()->isVectorType()) { + if ((S.LangOpts.OpenCL || S.LangOpts.ZVector) && + !LHS.get()->getType()->isVectorType()) { S.Diag(Loc, diag::err_shift_rhs_only_vector) << RHS.get()->getType() << LHS.get()->getType() << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); return QualType(); } if (!IsCompAssign) { - LHS = S.UsualUnaryConversions(LHS.get()); + if (S.LangOpts.OpenCL || S.LangOpts.ZVector) + LHS = S.UsualUnaryConversions(LHS.get()); + else + LHS = S.DefaultFunctionArrayLvalueConversion(LHS.get()); if (LHS.isInvalid()) return QualType(); } RHS = S.UsualUnaryConversions(RHS.get()); if (RHS.isInvalid()) return QualType(); QualType LHSType = LHS.get()->getType(); - const VectorType *LHSVecTy = LHSType->castAs<VectorType>(); - QualType LHSEleType = LHSVecTy->getElementType(); + const VectorType *LHSVecTy = LHSType->getAs<VectorType>(); + QualType LHSEleType = LHSVecTy ? LHSVecTy->getElementType() : LHSType; // Note that RHS might not be a vector. QualType RHSType = RHS.get()->getType(); @@ -8758,7 +8762,19 @@ return QualType(); } - if (RHSVecTy) { + if (!LHSVecTy) { + assert(RHSVecTy); + if (IsCompAssign) + return RHSType; + if (LHSEleType != RHSEleType) { + LHS = S.ImpCastExprToType(LHS.get(),RHSEleType, CK_IntegralCast); + LHSEleType = RHSEleType; + } + QualType VecTy = + S.Context.getExtVectorType(LHSEleType, RHSVecTy->getNumElements()); + LHS = S.ImpCastExprToType(LHS.get(), VecTy, CK_VectorSplat); + LHSType = VecTy; + } else if (RHSVecTy) { // OpenCL v1.1 s6.3.j says that for vector types, the operators // are applied component-wise. So if RHS is a vector, then ensure // that the number of elements is the same as LHS... @@ -8768,6 +8784,62 @@ << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); return QualType(); } + if (!S.LangOpts.OpenCL && !S.LangOpts.ZVector) { + const BuiltinType *LHSBT = LHSEleType->getAs<clang::BuiltinType>(); + const BuiltinType *RHSBT = RHSEleType->getAs<clang::BuiltinType>(); + if (LHSBT != RHSBT) { + BuiltinType::Kind LHSKind = LHSBT->getKind(); + BuiltinType::Kind RHSKind = RHSBT->getKind(); + bool DiffSizes = true; + switch (LHSKind) { + case BuiltinType::Char_S: + DiffSizes = + RHSKind != BuiltinType::Char_U && RHSKind != BuiltinType::UChar; + break; + case BuiltinType::Char_U: + DiffSizes = + RHSKind != BuiltinType::Char_S && RHSKind != BuiltinType::UChar; + break; + case BuiltinType::UChar: + DiffSizes = + RHSKind != BuiltinType::Char_U && RHSKind != BuiltinType::Char_S; + break; + case BuiltinType::Short: + DiffSizes = RHSKind != BuiltinType::UShort; + break; + case BuiltinType::UShort: + DiffSizes = RHSKind != BuiltinType::Short; + break; + case BuiltinType::Int: + DiffSizes = RHSKind != BuiltinType::UInt; + break; + case BuiltinType::UInt: + DiffSizes = RHSKind != BuiltinType::Int; + break; + case BuiltinType::Long: + DiffSizes = RHSKind != BuiltinType::ULong; + break; + case BuiltinType::ULong: + DiffSizes = RHSKind != BuiltinType::Long; + break; + case BuiltinType::LongLong: + DiffSizes = RHSKind != BuiltinType::ULongLong; + break; + case BuiltinType::ULongLong: + DiffSizes = RHSKind != BuiltinType::LongLong; + break; + default: + DiffSizes = true; + break; + } + if (DiffSizes) { + S.Diag(Loc, diag::err_typecheck_vector_element_sizes_not_equal) + << LHS.get()->getType() << RHS.get()->getType() + << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); + return QualType(); + } + } + } } else { // ...else expand RHS to match the number of elements in LHS. QualType VecTy = Index: llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2299,6 +2299,8 @@ "cannot convert between vector and non-scalar values (%0 and %1)">; def err_typecheck_vector_lengths_not_equal : Error< "vector operands do not have the same number of elements (%0 and %1)">; +def err_typecheck_vector_element_sizes_not_equal : Error< + "vector operands do not have the same elements sizes (%0 and %1)">; def err_ext_vector_component_exceeds_length : Error< "vector component access exceeds type %0">; def err_ext_vector_component_name_illegal : Error< Index: llvm/tools/clang/test/Sema/vecshift.c =================================================================== --- llvm/tools/clang/test/Sema/vecshift.c +++ llvm/tools/clang/test/Sema/vecshift.c @@ -0,0 +1,80 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef __attribute__((__ext_vector_type__(8))) char vector_char8; +typedef __attribute__((__ext_vector_type__(8))) short vector_short8; +typedef __attribute__((__ext_vector_type__(8))) int vector_int8; +typedef __attribute__((__ext_vector_type__(8))) unsigned char vector_uchar8; +typedef __attribute__((__ext_vector_type__(8))) unsigned short vector_ushort8; +typedef __attribute__((__ext_vector_type__(8))) unsigned int vector_uint8; +typedef __attribute__((__ext_vector_type__(4))) char vector_char4; +typedef __attribute__((__ext_vector_type__(4))) short vector_short4; +typedef __attribute__((__ext_vector_type__(4))) int vector_int4; +typedef __attribute__((__ext_vector_type__(4))) unsigned char vector_uchar4; +typedef __attribute__((__ext_vector_type__(4))) unsigned short vector_ushort4; +typedef __attribute__((__ext_vector_type__(4))) unsigned int vector_uint4; + +char c; +short s; +int i; +unsigned char uc; +unsigned short us; +unsigned int ui; +vector_char8 vc8; +vector_short8 vs8; +vector_int8 vi8; +vector_uchar8 vuc8; +vector_ushort8 vus8; +vector_uint8 vui8; +vector_char4 vc4; +vector_short4 vs4; +vector_int4 vi4; +vector_uchar4 vuc4; +vector_ushort4 vus4; +vector_uint4 vui4; + +void foo() { + vc8 = 1 << vc8; + vuc8 = 1 << vuc8; + vi8 = 1 << vi8; + vui8 = 1 << vui8; + vs8 = 1 << vs8; + vus8 = 1 << vus8; + + vc8 = c << vc8; + vuc8 = i << vuc8; + vi8 = uc << vi8; + vui8 = us << vui8; + vs8 = ui << vs8; + vus8 = 1 << vus8; + + vc8 = vc8 << vc8; + vi8 = vi8 << vuc8; // expected-error {{vector operands do not have the same elements sizes}} + vuc8 = vuc8 << vi8; // expected-error {{vector operands do not have the same elements sizes}} + vus8 = vus8 << vui8; // expected-error {{vector operands do not have the same elements sizes}} + vui8 = vui8 << vs8; // expected-error {{vector operands do not have the same elements sizes}} + + vc4 = vc4 << vc8; // expected-error {{vector operands do not have the same number of elements}} + vi4 = vi4 << vuc8; // expected-error {{vector operands do not have the same number of elements}} + vuc4 = vuc4 << vi8; // expected-error {{vector operands do not have the same number of elements}} + vus4 = vus4 << vui8; // expected-error {{vector operands do not have the same number of elements}} + vui4 = vui4 << vs8; // expected-error {{vector operands do not have the same number of elements}} + + + vc8 = vc8 << vc4; // expected-error {{vector operands do not have the same number of elements}} + vi8 = vi8 << vuc4; // expected-error {{vector operands do not have the same number of elements}} + vuc8 = vuc8 << vi4; // expected-error {{vector operands do not have the same number of elements}} + vus8 = vus8 << vui4; // expected-error {{vector operands do not have the same number of elements}} + vui8 = vui8 << vs4; // expected-error {{vector operands do not have the same number of elements}} + + vc8 <<= vc8; + vi8 <<= vuc8; // expected-error {{vector operands do not have the same elements sizes}} + vuc8 <<= vi8; // expected-error {{vector operands do not have the same elements sizes}} + vus8 <<= vui8; // expected-error {{vector operands do not have the same elements sizes}} + vui8 <<= vs8; // expected-error {{vector operands do not have the same elements sizes}} + + c <<= vc8; // expected-error {{assigning to 'char' from incompatible type}} + i <<= vuc8; // expected-error {{assigning to 'int' from incompatible type}} + uc <<= vi8; // expected-error {{assigning to 'unsigned char' from incompatible type}} + us <<= vui8; // expected-error {{assigning to 'unsigned short' from incompatible type}} + ui <<= vs8; // expected-error {{assigning to 'unsigned int' from incompatible type}} +}
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits