[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