diff options
author | Nate Begeman <natebegeman@mac.com> | 2009-06-28 02:36:38 +0000 |
---|---|---|
committer | Nate Begeman <natebegeman@mac.com> | 2009-06-28 02:36:38 +0000 |
commit | bd956c429040a41c7e9e4fdd3063ec0ab98457cb (patch) | |
tree | ada8f3690cc2719f70171e9775cedcdc4959d5d5 /clang/lib | |
parent | 9d09e20142f6767eadcfb27318f6850c1d371c3e (diff) | |
download | bcm5719-llvm-bd956c429040a41c7e9e4fdd3063ec0ab98457cb.tar.gz bcm5719-llvm-bd956c429040a41c7e9e4fdd3063ec0ab98457cb.zip |
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.
llvm-svn: 74404
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 75 |
1 files changed, 46 insertions, 29 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 464ee939ffe..6e111651066 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2940,9 +2940,13 @@ bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, QualType SrcTy) { 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 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { 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 @@ inline QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, } } - // 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() |