[cfe-commits] r74404 - in /cfe/trunk: lib/Sema/SemaExpr.cpp test/Sema/ext_vector_casts.c

Nate Begeman natebegeman at mac.com
Sat Jun 27 19:36:39 PDT 2009


Author: sampo
Date: Sat Jun 27 21:36:38 2009
New Revision: 74404

URL: http://llvm.org/viewvc/llvm-project?rev=74404&view=rev
Log:
OpenCL 1.0 support: 
Handle rules for ExtVector + ExtVector and ExtVector + Scalar operations. 
Fix problem Eli noticed where we were allowing pointer types to be splatted to
vector elements.

Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/Sema/ext_vector_casts.c

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Jun 27 21:36:38 2009
@@ -2940,9 +2940,13 @@
     return false;
   }
 
-  // All scalar -> ext vector "c-style" casts are legal; the appropriate
+  // All non-pointer scalars can be cast to ExtVector type.  The appropriate
   // conversion will take place first from scalar to elt type, and then
   // splat from elt type to vector.
+  if (SrcTy->isPointerType())
+    return Diag(R.getBegin(),
+                diag::err_invalid_conversion_between_vector_and_scalar)
+      << DestTy << SrcTy << R;
   return false;
 }
 
@@ -3374,12 +3378,16 @@
     return IncompatibleObjCQualifiedId;
   }
 
+  // Allow scalar to ExtVector assignments, and assignments of an ExtVector type
+  // to the same ExtVector type.
+  if (lhsType->isExtVectorType()) {
+    if (rhsType->isExtVectorType())
+      return lhsType == rhsType ? Compatible : Incompatible;
+    if (!rhsType->isVectorType() && rhsType->isArithmeticType())
+      return Compatible;
+  }
+  
   if (lhsType->isVectorType() || rhsType->isVectorType()) {
-    // For ExtVector, allow vector splats; float -> <n x float>
-    if (const ExtVectorType *LV = lhsType->getAsExtVectorType())
-      if (LV->getElementType() == rhsType)
-        return Compatible;
-
     // 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.
@@ -3606,32 +3614,41 @@
     }
   }
 
-  // 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()) {
-    QualType eltType = V->getElementType();
-
-    if ((eltType->getAsBuiltinType() == rhsType->getAsBuiltinType()) ||
-        (eltType->isIntegerType() && isa<IntegerLiteral>(rex)) ||
-        (eltType->isFloatingType() && isa<FloatingLiteral>(rex))) {
-      ImpCastExprToType(rex, lhsType);
-      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()) {
+    swapped = true;
+    std::swap(rex, lex);
+    std::swap(rhsType, lhsType);
   }
-
-  // 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()) {
-    QualType eltType = V->getElementType();
-
-    if ((eltType->getAsBuiltinType() == lhsType->getAsBuiltinType()) ||
-        (eltType->isIntegerType() && isa<IntegerLiteral>(lex)) ||
-        (eltType->isFloatingType() && isa<FloatingLiteral>(lex))) {
-      ImpCastExprToType(lex, rhsType);
-      return rhsType;
+  
+  // Handle the case of an ext vector and scalar
+  if (const ExtVectorType *LV = lhsType->getAsExtVectorType()) {
+    QualType EltTy = LV->getElementType();
+    if (EltTy->isIntegralType() && rhsType->isIntegralType()) {
+      if (Context.getIntegerTypeOrder(EltTy, rhsType) >= 0) {
+        ImpCastExprToType(rex, EltTy);
+        rex = new (Context) CStyleCastExpr(lhsType, rex, lhsType,
+                                           rex->getSourceRange().getBegin(),
+                                           rex->getSourceRange().getEnd());
+        if (swapped) std::swap(rex, lex);
+        return lhsType;
+      }
+    }
+    if (EltTy->isRealFloatingType() && rhsType->isScalarType() &&
+        rhsType->isRealFloatingType()) {
+      if (Context.getFloatingTypeOrder(EltTy, rhsType) >= 0) {
+        ImpCastExprToType(rex, EltTy);
+        rex = new (Context) CStyleCastExpr(lhsType, rex, lhsType,
+                                           rex->getSourceRange().getBegin(),
+                                           rex->getSourceRange().getEnd());
+        if (swapped) std::swap(rex, lex);
+        return lhsType;
+      }
     }
   }
-
+  
   // You cannot convert between vector values of different size.
   Diag(Loc, diag::err_typecheck_vector_not_convertable)
     << lex->getType() << rex->getType()

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=74404&r1=74403&r2=74404&view=diff

==============================================================================
--- cfe/trunk/test/Sema/ext_vector_casts.c (original)
+++ cfe/trunk/test/Sema/ext_vector_casts.c Sat Jun 27 21:36:38 2009
@@ -2,6 +2,7 @@
 
 typedef __attribute__(( ext_vector_type(2) )) float float2;
 typedef __attribute__(( ext_vector_type(4) )) int int4;
+typedef __attribute__(( ext_vector_type(8) )) short short8;
 typedef __attribute__(( ext_vector_type(4) )) float float4;
 typedef float t3 __attribute__ ((vector_size (16)));
 
@@ -9,8 +10,12 @@
     float2 vec2;
     float4 vec4, vec4_2;
     int4 ivec4;
+    short8 ish8;
     t3 vec4_3;
+    int *ptr;
+    int i;
     
+    vec4 = 5.0f;
     vec4 = (float4)5.0f;
     vec4 = (float4)5;
     vec4 = (float4)vec4_3;
@@ -19,5 +24,22 @@
     ivec4 = (int4)5;
     ivec4 = (int4)vec4_3;
     
+    i = (int)ivec4; // expected-error {{invalid conversion between vector type 'int4' and integer type 'int' of different size}}
+    i = ivec4; // expected-error {{incompatible type assigning 'int4', expected 'int'}}
+    
+    ivec4 = (int4)ptr; // expected-error {{invalid conversion between vector type 'int4' and scalar type 'int *'}}
+    
     vec4 = (float4)vec2; // expected-error {{invalid conversion between ext-vector type 'float4' and 'float2'}}
+    
+    ish8 += 5; // expected-error {{can't convert between vector values of different size ('short8' and 'int')}}
+    ish8 += (short)5;
+    ivec4 *= 5;
+     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 += (int4)vec4;
+    ivec4 -= ivec4;
+    ivec4 |= ivec4;
+    ivec4 += ptr; // expected-error {{can't convert between vector values of different size ('int4' and 'int *')}}
 }





More information about the cfe-commits mailing list