[cfe-commits] r53565 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaExpr.cpp test/Sema/vector-assign.c

Nate Begeman natebegeman at mac.com
Mon Jul 14 11:02:47 PDT 2008


Author: sampo
Date: Mon Jul 14 13:02:46 2008
New Revision: 53565

URL: http://llvm.org/viewvc/llvm-project?rev=53565&view=rev
Log:
http://llvm.org/bugs/show_bug.cgi?id=2523

Add some code to handle vector comparisons, which is the language side
of the llvm vicmp/vfcmp instructions.  Also make the vector-vector and
vector-scalar asign checks a bit more sane under the presence of lax vector
conversions.

Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/Sema/vector-assign.c

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=53565&r1=53564&r2=53565&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Jul 14 13:02:46 2008
@@ -812,7 +812,6 @@
     
   /// type checking binary operators (subroutines of ActOnBinOp).
   inline QualType InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex);
-  inline QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex);
   inline QualType CheckMultiplyDivideOperands( // C99 6.5.5
     Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false); 
   inline QualType CheckRemainderOperands( // C99 6.5.5
@@ -838,6 +837,11 @@
     Expr *&lex, Expr *&rex, SourceLocation OpLoc);
   inline QualType CheckConditionalOperands( // C99 6.5.15
     Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
+
+  /// type checking for vector binary operators.
+  inline QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex);
+  inline QualType CheckVectorCompareOperands(Expr *&lex, Expr *&rx,
+                                             SourceLocation l, bool isRel);
   
   /// type checking unary operators (subroutines of ActOnUnaryOp).
   /// C99 6.5.3.1, 6.5.3.2, 6.5.3.4

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=53565&r1=53564&r2=53565&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jul 14 13:02:46 2008
@@ -1370,24 +1370,19 @@
     return Incompatible;
   }
 
-  if (isa<VectorType>(lhsType) || isa<VectorType>(rhsType)) {
+  if (lhsType->isVectorType() || rhsType->isVectorType()) {
     // For ExtVector, allow vector splats; float -> <n x float>
-    if (const ExtVectorType *LV = dyn_cast<ExtVectorType>(lhsType)) {
-      if (LV->getElementType().getTypePtr() == rhsType.getTypePtr())
+    if (const ExtVectorType *LV = lhsType->getAsExtVectorType())
+      if (LV->getElementType() == rhsType)
         return Compatible;
-    }
 
-    // If LHS and RHS are both vectors of integer or both vectors of floating
-    // point types, and the total vector length is the same, allow the
-    // conversion.  This is a bitcast; no bits are changed but the result type
-    // is different.
+    // 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.
     if (getLangOptions().LaxVectorConversions &&
         lhsType->isVectorType() && rhsType->isVectorType()) {
-      if ((lhsType->isIntegerType() && rhsType->isIntegerType()) ||
-          (lhsType->isRealFloatingType() && rhsType->isRealFloatingType())) {
-        if (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType))
-          return Compatible;
-      }
+      if (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType))
+        return Compatible;
     }
     return Incompatible;
   }      
@@ -1472,25 +1467,40 @@
   QualType lhsType = lex->getType().getCanonicalType().getUnqualifiedType();
   QualType rhsType = rex->getType().getCanonicalType().getUnqualifiedType();
   
-  // make sure the vector types are identical. 
+  // If the vector types are identical, return.
   if (lhsType == rhsType)
     return lhsType;
 
-  // if the lhs is an extended vector and the rhs is a scalar of the same type,
-  // promote the rhs to the vector type.
+  // 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->getAsVectorType())
+      if (const VectorType *RV = rhsType->getAsVectorType())
+        if (LV->getElementType() == RV->getElementType() &&
+            LV->getNumElements() == RV->getNumElements())
+          return lhsType->isExtVectorType() ? lhsType : rhsType;
+
+  // If the lhs is an extended vector and the rhs is a scalar of the same type
+  // or a literal, promote the rhs to the vector type.
   if (const ExtVectorType *V = lhsType->getAsExtVectorType()) {
-    if (V->getElementType().getCanonicalType().getTypePtr()
-        == rhsType.getCanonicalType().getTypePtr()) {
+    QualType eltType = V->getElementType();
+    
+    if ((eltType->getAsBuiltinType() == rhsType->getAsBuiltinType()) || 
+        (eltType->isIntegerType() && isa<IntegerLiteral>(rex)) ||
+        (eltType->isFloatingType() && isa<FloatingLiteral>(rex))) {
       ImpCastExprToType(rex, lhsType);
       return lhsType;
     }
   }
 
-  // if the rhs is an extended vector and the lhs is a scalar of the same type,
+  // If the rhs is an extended vector and the lhs is a scalar of the same type,
   // promote the lhs to the vector type.
   if (const ExtVectorType *V = rhsType->getAsExtVectorType()) {
-    if (V->getElementType().getCanonicalType().getTypePtr()
-        == lhsType.getCanonicalType().getTypePtr()) {
+    QualType eltType = V->getElementType();
+
+    if ((eltType->getAsBuiltinType() == lhsType->getAsBuiltinType()) || 
+        (eltType->isIntegerType() && isa<IntegerLiteral>(lex)) ||
+        (eltType->isFloatingType() && isa<FloatingLiteral>(lex))) {
       ImpCastExprToType(lex, rhsType);
       return rhsType;
     }
@@ -1656,6 +1666,9 @@
 // C99 6.5.8
 QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation loc,
                                     bool isRelational) {
+  if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
+    return CheckVectorCompareOperands(lex, rex, loc, isRelational);
+  
   // C99 6.5.8p3 / C99 6.5.9p4
   if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType())
     UsualArithmeticConversions(lex, rex);
@@ -1740,6 +1753,55 @@
   return InvalidOperands(loc, lex, rex);
 }
 
+/// CheckVectorCompareOperands - vector comparisons are a clang extension that
+/// operates on extended vector types.  Instead of producing an IntTy result, 
+/// like a scalar comparison, a vector comparison produces a vector of integer
+/// types.
+QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex,
+                                          SourceLocation loc,
+                                          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);
+  if (vType.isNull())
+    return vType;
+  
+  QualType lType = lex->getType();
+  QualType rType = rex->getType();
+  
+  // For non-floating point types, check for self-comparisons of the form
+  // x == x, x != x, x < x, etc.  These always evaluate to a constant, and
+  // often indicate logic errors in the program.
+  if (!lType->isFloatingType()) {
+    if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(lex->IgnoreParens()))
+      if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(rex->IgnoreParens()))
+        if (DRL->getDecl() == DRR->getDecl())
+          Diag(loc, diag::warn_selfcomparison);      
+  }
+  
+  // Check for comparisons of floating point operands using != and ==.
+  if (!isRelational && lType->isFloatingType()) {
+    assert (rType->isFloatingType());
+    CheckFloatComparison(loc,lex,rex);
+  }
+  
+  // Return the type for the comparison, which is the same as vector type for
+  // integer vectors, or an integer type of identical size and number of
+  // elements for floating point vectors.
+  if (lType->isIntegerType())
+    return lType;
+  
+  const VectorType *VTy = lType->getAsVectorType();
+
+  // FIXME: need to deal with non-32b int / non-64b long long
+  unsigned TypeSize = Context.getTypeSize(VTy->getElementType());
+  if (TypeSize == 32) {
+    return Context.getExtVectorType(Context.IntTy, VTy->getNumElements());
+  }
+  assert(TypeSize == 64 && "Unhandled vector element size in vector compare");
+  return Context.getExtVectorType(Context.LongLongTy, VTy->getNumElements());
+}
+
 inline QualType Sema::CheckBitwiseOperands(
   Expr *&lex, Expr *&rex, SourceLocation loc, bool isCompAssign) 
 {

Modified: cfe/trunk/test/Sema/vector-assign.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vector-assign.c?rev=53565&r1=53564&r2=53565&view=diff

==============================================================================
--- cfe/trunk/test/Sema/vector-assign.c (original)
+++ cfe/trunk/test/Sema/vector-assign.c Mon Jul 14 13:02:46 2008
@@ -14,12 +14,12 @@
   
   v1 = v2; 
   v1 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v2s'}}
-  v1 = v4; // expected-error {{incompatible type assigning 'v2f', expected 'v2s'}}
+  v1 = v4; 
   v1 = v5;
   
   v2 = v1;
   v2 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v2u'}}
-  v2 = v4; // expected-error {{incompatible type assigning 'v2f', expected 'v2u'}}
+  v2 = v4; 
   v2 = v5;
   
   v3 = v1; // expected-error {{incompatible type assigning 'v2s', expected 'v1s'}}
@@ -27,15 +27,15 @@
   v3 = v4; // expected-error {{incompatible type assigning 'v2f', expected 'v1s'}}
   v3 = v5; // expected-error {{incompatible type assigning 'v4ss', expected 'v1s'}}
   
-  v4 = v1; // expected-error {{incompatible type assigning 'v2s', expected 'v2f'}}
-  v4 = v2; // expected-error {{incompatible type assigning 'v2u', expected 'v2f'}}
+  v4 = v1; 
+  v4 = v2; 
   v4 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v2f'}}
-  v4 = v5; // expected-error {{incompatible type assigning 'v4ss', expected 'v2f'}}
+  v4 = v5;
   
   v5 = v1;
   v5 = v2;
   v5 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v4ss'}}
-  v5 = v4; // expected-error {{incompatible type assigning 'v2f', expected 'v4ss'}}
+  v5 = v4;
 }
 
 // PR2263





More information about the cfe-commits mailing list