diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-08-06 10:14:59 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-08-06 10:14:59 +0000 |
commit | 255210ef415b9893f0e3794e8d9a704194c12f3c (patch) | |
tree | 8c016aed60efdd19fbc225aa8ee5eebbae8e0847 | |
parent | 2b602adf9798eaf13850efaf8ed41c69d3cf7da6 (diff) |
Introduce implicit conversions between AltiVec vectors and GCC
vectors, from Anton Yartsev!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110437 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/ASTContext.h | 5 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 27 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 24 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 22 | ||||
-rw-r--r-- | test/Sema/altivec-init.c | 19 | ||||
-rw-r--r-- | test/SemaCXX/altivec.cpp | 18 |
6 files changed, 96 insertions, 19 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 3c94970016..df96de023d 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -906,6 +906,11 @@ public: /// Qualifiers::GC getObjCGCAttrKind(const QualType &Ty) const; + /// areCompatibleVectorTypes - Return true if the given vector types either + /// are of the same unqualified type or if one is GCC and other - equivalent + /// AltiVec vector type. + bool areCompatibleVectorTypes(QualType FirstVec, QualType SecondVec); + /// isObjCNSObjectType - Return true if this is an NSObject object with /// its NSObject attribute set. bool isObjCNSObjectType(QualType Ty) const; diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 43873a4efd..22e1ebf569 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1540,10 +1540,7 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts, // If the element type isn't canonical, this won't be a canonical type either, // so fill in the canonical type field. QualType Canonical; - if (!vecType.isCanonical() || (AltiVecSpec == VectorType::AltiVec)) { - // pass VectorType::NotAltiVec for AltiVecSpec to make AltiVec canonical - // vector type (except 'vector bool ...' and 'vector Pixel') the same as - // the equivalent GCC vector types + if (!vecType.isCanonical()) { Canonical = getVectorType(getCanonicalType(vecType), NumElts, VectorType::NotAltiVec); @@ -4170,6 +4167,28 @@ static bool areCompatVectorTypes(const VectorType *LHS, LHS->getNumElements() == RHS->getNumElements(); } +bool ASTContext::areCompatibleVectorTypes(QualType FirstVec, + QualType SecondVec) { + assert(FirstVec->isVectorType() && "FirstVec should be a vector type"); + assert(SecondVec->isVectorType() && "SecondVec should be a vector type"); + + if (hasSameUnqualifiedType(FirstVec, SecondVec)) + return true; + + // AltiVec vectors types are identical to equivalent GCC vector types + const VectorType *First = FirstVec->getAs<VectorType>(); + const VectorType *Second = SecondVec->getAs<VectorType>(); + if ((((First->getAltiVecSpecific() == VectorType::AltiVec) && + (Second->getAltiVecSpecific() == VectorType::NotAltiVec)) || + ((First->getAltiVecSpecific() == VectorType::NotAltiVec) && + (Second->getAltiVecSpecific() == VectorType::AltiVec))) && + hasSameType(First->getElementType(), Second->getElementType()) && + (First->getNumElements() == Second->getNumElements())) + return true; + + return false; +} + //===----------------------------------------------------------------------===// // ObjCQualifiedIdTypesAreCompatible - Compatibility testing for qualified id's. //===----------------------------------------------------------------------===// diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 28b2e99537..46c5a65f75 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -4731,13 +4731,18 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { } if (lhsType->isVectorType() || rhsType->isVectorType()) { - // 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 (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType)) + if (lhsType->isVectorType() && rhsType->isVectorType()) { + // 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 && + (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType))) return IncompatibleVectors; + + // Allow assignments of an AltiVec vector type to an equivalent GCC + // vector type and vice versa + if (Context.areCompatibleVectorTypes(lhsType, rhsType)) + return Compatible; } return Incompatible; } @@ -5012,6 +5017,13 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) { } } + // Handle the case of equivalent AltiVec and GCC vector types + if (lhsType->isVectorType() && rhsType->isVectorType() && + Context.areCompatibleVectorTypes(lhsType, rhsType)) { + ImpCastExprToType(lex, rhsType, CastExpr::CK_BitCast); + return rhsType; + } + // 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; diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 037bc7b76b..5dfbe09709 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -850,16 +850,20 @@ static bool IsVectorConversion(ASTContext &Context, QualType FromType, return true; } } - - // If lax vector conversions are permitted and the vector types are of the - // same size, we can perform the conversion. - if (Context.getLangOptions().LaxVectorConversions && - FromType->isVectorType() && ToType->isVectorType() && - Context.getTypeSize(FromType) == Context.getTypeSize(ToType)) { - ICK = ICK_Vector_Conversion; - return true; + + // We can perform the conversion between vector types in the following cases: + // 1)vector types are equivalent AltiVec and GCC vector types + // 2)lax vector conversions are permitted and the vector types are of the + // same size + if (ToType->isVectorType() && FromType->isVectorType()) { + if (Context.areCompatibleVectorTypes(FromType, ToType) || + Context.getLangOptions().LaxVectorConversions && + (Context.getTypeSize(FromType) == Context.getTypeSize(ToType))) { + ICK = ICK_Vector_Conversion; + return true; + } } - + return false; } diff --git a/test/Sema/altivec-init.c b/test/Sema/altivec-init.c index 57abc9304d..b5758bc718 100644 --- a/test/Sema/altivec-init.c +++ b/test/Sema/altivec-init.c @@ -14,3 +14,22 @@ v8 foo(void) { // FIXME: test that (type)(fn)(args) still works with -faltivec // FIXME: test that c++ overloaded commas still work -faltivec } + +void __attribute__((__overloadable__)) f(v4 a) +{ +} + +void __attribute__((__overloadable__)) f(int a) +{ +} + +void test() +{ + v4 vGCC; + vector int vAltiVec; + + f(vAltiVec); + vGCC = vAltiVec; + vGCC = vGCC > vAltiVec; + vAltiVec = 0 ? vGCC : vGCC; +} diff --git a/test/SemaCXX/altivec.cpp b/test/SemaCXX/altivec.cpp new file mode 100644 index 0000000000..cdfc00a5d4 --- /dev/null +++ b/test/SemaCXX/altivec.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -faltivec -fno-lax-vector-conversions -triple powerpc-unknown-unknown -verify %s + +typedef int V4i __attribute__((vector_size(16))); + +void f(V4i a) +{ +} + +void test() +{ + V4i vGCC; + vector int vAltiVec; + + f(vAltiVec); + vGCC = vAltiVec; + vGCC = vGCC > vAltiVec; + vAltiVec = 0 ? vGCC : vGCC; +} |