[cfe-commits] r133737 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp test/Sema/arm-neon-types.c test/Sema/ext_vector_casts.c test/SemaCXX/vector.cpp

Eli Friedman eli.friedman at gmail.com
Thu Jun 23 11:10:35 PDT 2011


Author: efriedma
Date: Thu Jun 23 13:10:35 2011
New Revision: 133737

URL: http://llvm.org/viewvc/llvm-project?rev=133737&view=rev
Log:
Fix Sema::CheckVectorOperands so that it doesn't try to insert a cast expression into the LHS of a compound assignment.  Fixes compound assignment of various "compatible" vector types, including NEON-vector and gcc-vector types.

<rdar://problem/9640356>


Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/Sema/arm-neon-types.c
    cfe/trunk/test/Sema/ext_vector_casts.c
    cfe/trunk/test/SemaCXX/vector.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=133737&r1=133736&r2=133737&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Jun 23 13:10:35 2011
@@ -5559,7 +5559,8 @@
                                   SourceLocation QuestionLoc);
 
   /// type checking for vector binary operators.
-  QualType CheckVectorOperands(SourceLocation l, ExprResult &lex, ExprResult &rex);
+  QualType CheckVectorOperands(ExprResult &lex, ExprResult &rex,
+                               SourceLocation Loc, bool isCompAssign);
   QualType CheckVectorCompareOperands(ExprResult &lex, ExprResult &rx,
                                       SourceLocation l, bool isRel);
 

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=133737&r1=133736&r2=133737&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Jun 23 13:10:35 2011
@@ -4372,7 +4372,7 @@
 
   // Now check the two expressions.
   if (LHSTy->isVectorType() || RHSTy->isVectorType())
-    return CheckVectorOperands(QuestionLoc, LHS, RHS);
+    return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false);
 
   // OpenCL: If the condition is a vector, and both operands are scalar,
   // attempt to implicity convert them to the vector type to act like the
@@ -5470,7 +5470,8 @@
   return QualType();
 }
 
-QualType Sema::CheckVectorOperands(SourceLocation Loc, ExprResult &lex, ExprResult &rex) {
+QualType Sema::CheckVectorOperands(ExprResult &lex, ExprResult &rex,
+                                   SourceLocation Loc, bool isCompAssign) {
   // For conversion purposes, we ignore any qualifiers.
   // For example, "const float" and "float" are equivalent.
   QualType lhsType =
@@ -5482,42 +5483,33 @@
   if (lhsType == rhsType)
     return lhsType;
 
-  // Handle the case of a vector & extvector type of the same size and element
-  // type.  It would be nice if we only had one vector type someday.
-  if (getLangOptions().LaxVectorConversions) {
-    if (const VectorType *LV = lhsType->getAs<VectorType>()) {
-      if (const VectorType *RV = rhsType->getAs<VectorType>()) {
-        if (LV->getElementType() == RV->getElementType() &&
-            LV->getNumElements() == RV->getNumElements()) {
-          if (lhsType->isExtVectorType()) {
-            rex = ImpCastExprToType(rex.take(), lhsType, CK_BitCast);
-            return lhsType;
-          } 
-
-          lex = ImpCastExprToType(lex.take(), rhsType, CK_BitCast);
-          return rhsType;
-        } else if (Context.getTypeSize(lhsType) ==Context.getTypeSize(rhsType)){
-          // If we are allowing lax vector conversions, and LHS and RHS are both
-          // vectors, the total size only needs to be the same. This is a
-          // bitcast; no bits are changed but the result type is different.
-          rex = ImpCastExprToType(rex.take(), lhsType, CK_BitCast);
-          return lhsType;
-        }
-      }
-    }
-  }
-
   // Handle the case of equivalent AltiVec and GCC vector types
   if (lhsType->isVectorType() && rhsType->isVectorType() &&
       Context.areCompatibleVectorTypes(lhsType, rhsType)) {
-    lex = ImpCastExprToType(lex.take(), rhsType, CK_BitCast);
+    if (lhsType->isExtVectorType()) {
+      rex = ImpCastExprToType(rex.take(), lhsType, CK_BitCast);
+      return lhsType;
+    }
+
+    if (!isCompAssign)
+      lex = ImpCastExprToType(lex.take(), rhsType, CK_BitCast);
     return rhsType;
   }
 
+  if (getLangOptions().LaxVectorConversions &&
+      Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType)) {
+    // If we are allowing lax vector conversions, and LHS and RHS are both
+    // vectors, the total size only needs to be the same. This is a
+    // bitcast; no bits are changed but the result type is different.
+    // FIXME: Should we really be allowing this?
+    rex = ImpCastExprToType(rex.take(), lhsType, CK_BitCast);
+    return lhsType;
+  }
+
   // Canonicalize the ExtVector to the LHS, remember if we swapped so we can
   // swap back (so that we don't reverse the inputs to a subtract, for instance.
   bool swapped = false;
-  if (rhsType->isExtVectorType()) {
+  if (rhsType->isExtVectorType() && !isCompAssign) {
     swapped = true;
     std::swap(rex, lex);
     std::swap(rhsType, lhsType);
@@ -5550,6 +5542,7 @@
   }
 
   // Vectors of different size or scalar and non-ext-vector are errors.
+  if (swapped) std::swap(rex, lex);
   Diag(Loc, diag::err_typecheck_vector_not_convertable)
     << lex.get()->getType() << rex.get()->getType()
     << lex.get()->getSourceRange() << rex.get()->getSourceRange();
@@ -5559,7 +5552,7 @@
 QualType Sema::CheckMultiplyDivideOperands(
   ExprResult &lex, ExprResult &rex, SourceLocation Loc, bool isCompAssign, bool isDiv) {
   if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType())
-    return CheckVectorOperands(Loc, lex, rex);
+    return CheckVectorOperands(lex, rex, Loc, isCompAssign);
 
   QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
   if (lex.isInvalid() || rex.isInvalid())
@@ -5583,7 +5576,7 @@
   if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType()) {
     if (lex.get()->getType()->hasIntegerRepresentation() && 
         rex.get()->getType()->hasIntegerRepresentation())
-      return CheckVectorOperands(Loc, lex, rex);
+      return CheckVectorOperands(lex, rex, Loc, isCompAssign);
     return InvalidOperands(Loc, lex, rex);
   }
 
@@ -5605,7 +5598,7 @@
 QualType Sema::CheckAdditionOperands( // C99 6.5.6
   ExprResult &lex, ExprResult &rex, SourceLocation Loc, QualType* CompLHSTy) {
   if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType()) {
-    QualType compType = CheckVectorOperands(Loc, lex, rex);
+    QualType compType = CheckVectorOperands(lex, rex, Loc, CompLHSTy);
     if (CompLHSTy) *CompLHSTy = compType;
     return compType;
   }
@@ -5690,7 +5683,7 @@
 QualType Sema::CheckSubtractionOperands(ExprResult &lex, ExprResult &rex,
                                         SourceLocation Loc, QualType* CompLHSTy) {
   if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType()) {
-    QualType compType = CheckVectorOperands(Loc, lex, rex);
+    QualType compType = CheckVectorOperands(lex, rex, Loc, CompLHSTy);
     if (CompLHSTy) *CompLHSTy = compType;
     return compType;
   }
@@ -5913,7 +5906,7 @@
 
   // Vector shifts promote their scalar inputs to vector type.
   if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType())
-    return CheckVectorOperands(Loc, lex, rex);
+    return CheckVectorOperands(lex, rex, Loc, isCompAssign);
 
   // Shifts don't perform usual arithmetic conversions, they just do integer
   // promotions on each operand. C99 6.5.7p3
@@ -6382,7 +6375,7 @@
                                           bool isRelational) {
   // Check to make sure we're operating on vectors of the same type and width,
   // Allowing one side to be a scalar of element type.
-  QualType vType = CheckVectorOperands(Loc, lex, rex);
+  QualType vType = CheckVectorOperands(lex, rex, Loc, /*isCompAssign*/false);
   if (vType.isNull())
     return vType;
 
@@ -6437,7 +6430,7 @@
   if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType()) {
     if (lex.get()->getType()->hasIntegerRepresentation() &&
         rex.get()->getType()->hasIntegerRepresentation())
-      return CheckVectorOperands(Loc, lex, rex);
+      return CheckVectorOperands(lex, rex, Loc, isCompAssign);
     
     return InvalidOperands(Loc, lex, rex);
   }

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=133737&r1=133736&r2=133737&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Jun 23 13:10:35 2011
@@ -3636,7 +3636,7 @@
 
   // Extension: conditional operator involving vector types.
   if (LTy->isVectorType() || RTy->isVectorType())
-    return CheckVectorOperands(QuestionLoc, LHS, RHS);
+    return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false);
 
   //   -- The second and third operands have arithmetic or enumeration type;
   //      the usual arithmetic conversions are performed to bring them to a

Modified: cfe/trunk/test/Sema/arm-neon-types.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/arm-neon-types.c?rev=133737&r1=133736&r2=133737&view=diff
==============================================================================
--- cfe/trunk/test/Sema/arm-neon-types.c (original)
+++ cfe/trunk/test/Sema/arm-neon-types.c Thu Jun 23 13:10:35 2011
@@ -18,3 +18,10 @@
   // removed when that is fixed.
   return vcvt_n_f32_u32(x, 0); // expected-error {{argument should be a value from 1 to 32}} expected-error {{incompatible result type}}
 }
+
+typedef signed int vSInt32 __attribute__((__vector_size__(16)));
+int32x4_t test4(int32x4_t a, vSInt32 b) {
+  a += b;
+  b += a;
+  return b += a;
+}

Modified: cfe/trunk/test/Sema/ext_vector_casts.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/ext_vector_casts.c?rev=133737&r1=133736&r2=133737&view=diff
==============================================================================
--- cfe/trunk/test/Sema/ext_vector_casts.c (original)
+++ cfe/trunk/test/Sema/ext_vector_casts.c Thu Jun 23 13:10:35 2011
@@ -37,7 +37,7 @@
      vec4 /= 5.2f;
      vec4 %= 4; // expected-error {{invalid operands to binary expression ('float4' and 'int')}}
     ivec4 %= 4;
-    ivec4 += vec4; // expected-error {{can't convert between vector values of different size ('float4' and 'int4')}}
+    ivec4 += vec4; // expected-error {{can't convert between vector values of different size ('int4' and 'float4')}}
     ivec4 += (int4)vec4;
     ivec4 -= ivec4;
     ivec4 |= ivec4;

Modified: cfe/trunk/test/SemaCXX/vector.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/vector.cpp?rev=133737&r1=133736&r2=133737&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/vector.cpp (original)
+++ cfe/trunk/test/SemaCXX/vector.cpp Thu Jun 23 13:10:35 2011
@@ -176,10 +176,10 @@
   (void)(to_c16 * to_c16e);
   (void)(to_c16 / to_c16e);
   (void)(rto_c16 = c16e); // expected-error{{no viable overloaded '='}}
-  (void)(rto_c16 += to_c16e); // expected-error{{expression is not assignable}}
-  (void)(rto_c16 -= to_c16e); // expected-error{{expression is not assignable}}
-  (void)(rto_c16 *= to_c16e); // expected-error{{expression is not assignable}}
-  (void)(rto_c16 /= to_c16e); // expected-error{{expression is not assignable}}
+  (void)(rto_c16 += to_c16e);
+  (void)(rto_c16 -= to_c16e);
+  (void)(rto_c16 *= to_c16e);
+  (void)(rto_c16 /= to_c16e);
 
   (void)(Cond? to_c16 : to_c16e);
   (void)(Cond? to_ll16e : to_ll16);





More information about the cfe-commits mailing list