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 <[email protected]>
Date: Fri, Sep 2, 2016 at 3:00 AM
Subject: Re: [PATCH] D21678: Fix For pr28288 - Error message in shift of vector
values
To: [email protected], [email protected], [email protected],
[email protected], [email protected]
Cc: [email protected], [email protected], [email protected],
[email protected], [email protected]
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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits