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

Reply via email to