]> granicus.if.org Git - clang/commitdiff
Introduce implicit conversions between AltiVec vectors and GCC
authorDouglas Gregor <dgregor@apple.com>
Fri, 6 Aug 2010 10:14:59 +0000 (10:14 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 6 Aug 2010 10:14:59 +0000 (10:14 +0000)
vectors, from Anton Yartsev!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110437 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTContext.h
lib/AST/ASTContext.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaOverload.cpp
test/Sema/altivec-init.c
test/SemaCXX/altivec.cpp [new file with mode: 0644]

index 3c949700168cd80f675cdfbea1c99e000296ce5c..df96de023df60cd340b2b897cec856de65d152dc 100644 (file)
@@ -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;
index 43873a4efd7341409e882a8d0b26a17de8285de9..22e1ebf569705893c335ce579b9ded526f018a35 100644 (file)
@@ -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.
 //===----------------------------------------------------------------------===//
index 28b2e99537592bd37377d588aaf833d620a3edb5..46c5a65f75ddbdd7c6fec17e8175f1e47851259e 100644 (file)
@@ -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;
index 037bc7b76b7e9917e8126d90cffce88199512265..5dfbe09709fbdaae23f730210af0e89bc7706ce5 100644 (file)
@@ -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;
 }
   
index 57abc9304d5bedac5156e4499b32f4791bb21158..b5758bc718379b72d5e65a54b64aae1c46abdd8d 100644 (file)
@@ -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 (file)
index 0000000..cdfc00a
--- /dev/null
@@ -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;
+}