r203175 - C. Compare vector sizes using their raw element size instead of

Fariborz Jahanian fjahanian at apple.com
Thu Mar 6 14:47:10 PST 2014


Author: fjahanian
Date: Thu Mar  6 16:47:09 2014
New Revision: 203175

URL: http://llvm.org/viewvc/llvm-project?rev=203175&view=rev
Log:
C. Compare vector sizes using their raw element size instead of
getTypeSize (which rounds up sizes) in order to issue diagnostics 
when casting to mismatched vector sizes; instead of crashing in IRGen.
// rdar:// 16196902. Reviewed offline by John McCall.

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=203175&r1=203174&r2=203175&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Mar  6 16:47:09 2014
@@ -5049,12 +5049,55 @@ CastKind Sema::PrepareScalarCast(ExprRes
   llvm_unreachable("Unhandled scalar cast");
 }
 
+static bool breakDownVectorType(QualType type, uint64_t &len,
+                                QualType &eltType) {
+  // Vectors are simple.
+  if (const VectorType *vecType = type->getAs<VectorType>()) {
+    len = vecType->getNumElements();
+    eltType = vecType->getElementType();
+    assert(eltType->isScalarType());
+    return true;
+  }
+  
+  // We allow lax conversion to and from non-vector types, but only if
+  // they're real types (i.e. non-complex, non-pointer scalar types).
+  if (!type->isRealType()) return false;
+  
+  len = 1;
+  eltType = type;
+  return true;
+}
+
+static bool VectorTypesMatch(Sema &S, QualType srcTy, QualType destTy) {
+  uint64_t srcLen, destLen;
+  QualType srcElt, destElt;
+  if (!breakDownVectorType(srcTy, srcLen, srcElt)) return false;
+  if (!breakDownVectorType(destTy, destLen, destElt)) return false;
+  
+  // ASTContext::getTypeSize will return the size rounded up to a
+  // power of 2, so instead of using that, we need to use the raw
+  // element size multiplied by the element count.
+  uint64_t srcEltSize = S.Context.getTypeSize(srcElt);
+  uint64_t destEltSize = S.Context.getTypeSize(destElt);
+  
+  return (srcLen * srcEltSize == destLen * destEltSize);
+}
+
+/// Is this a legal conversion between two known vector types?
+bool Sema::isLaxVectorConversion(QualType srcTy, QualType destTy) {
+  assert(destTy->isVectorType() || srcTy->isVectorType());
+  
+  if (!Context.getLangOpts().LaxVectorConversions)
+    return false;
+  return VectorTypesMatch(*this, srcTy, destTy);
+}
+
 bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
                            CastKind &Kind) {
   assert(VectorTy->isVectorType() && "Not a vector type!");
 
   if (Ty->isVectorType() || Ty->isIntegerType()) {
-    if (Context.getTypeSize(VectorTy) != Context.getTypeSize(Ty))
+    if (!VectorTypesMatch(*this, Ty, VectorTy))
       return Diag(R.getBegin(),
                   Ty->isVectorType() ?
                   diag::err_invalid_conversion_between_vectors :
@@ -5080,7 +5123,7 @@ ExprResult Sema::CheckExtVectorCast(Sour
   // In OpenCL, casts between vectors of different types are not allowed.
   // (See OpenCL 6.2).
   if (SrcTy->isVectorType()) {
-    if (Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy)
+    if (!VectorTypesMatch(*this, SrcTy, DestTy)
         || (getLangOpts().OpenCL &&
             (DestTy.getCanonicalType() != SrcTy.getCanonicalType()))) {
       Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors)
@@ -6657,46 +6700,6 @@ QualType Sema::InvalidOperands(SourceLoc
   return QualType();
 }
 
-static bool breakDownVectorType(QualType type, uint64_t &len,
-                                QualType &eltType) {
-  // Vectors are simple.
-  if (const VectorType *vecType = type->getAs<VectorType>()) {
-    len = vecType->getNumElements();
-    eltType = vecType->getElementType();
-    assert(eltType->isScalarType());
-    return true;
-  }
-
-  // We allow lax conversion to and from non-vector types, but only if
-  // they're real types (i.e. non-complex, non-pointer scalar types).
-  if (!type->isRealType()) return false;
-
-  len = 1;
-  eltType = type;
-  return true;
-}
-
-/// Is this a legal conversion between two known vector types?
-bool Sema::isLaxVectorConversion(QualType srcTy, QualType destTy) {
-  assert(destTy->isVectorType() || srcTy->isVectorType());
-
-  if (!Context.getLangOpts().LaxVectorConversions)
-    return false;
-
-  uint64_t srcLen, destLen;
-  QualType srcElt, destElt;
-  if (!breakDownVectorType(srcTy, srcLen, srcElt)) return false;
-  if (!breakDownVectorType(destTy, destLen, destElt)) return false;
-
-  // ASTContext::getTypeSize will return the size rounded up to a
-  // power of 2, so instead of using that, we need to use the raw
-  // element size multiplied by the element count.
-  uint64_t srcEltSize = Context.getTypeSize(srcElt);
-  uint64_t destEltSize = Context.getTypeSize(destElt);
-
-  return (srcLen * srcEltSize == destLen * destEltSize);
-}
-
 /// Try to convert a value of non-vector type to a vector type by
 /// promoting (and only promoting) the type to the element type of the
 /// vector and then performing a vector splat.

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=203175&r1=203174&r2=203175&view=diff
==============================================================================
--- cfe/trunk/test/Sema/ext_vector_casts.c (original)
+++ cfe/trunk/test/Sema/ext_vector_casts.c Thu Mar  6 16:47:09 2014
@@ -79,3 +79,13 @@ stride4 RDar15091442_get_stride4(int4 x,
     return stride;
 }
 
+// rdar://16196902
+typedef __attribute__((ext_vector_type(4))) float float32x4_t;
+
+typedef float C3DVector3 __attribute__((ext_vector_type(3)));
+
+extern float32x4_t vabsq_f32(float32x4_t __a);
+
+C3DVector3 Func(const C3DVector3 a) {
+    return (C3DVector3)vabsq_f32((float32x4_t)a); // expected-error {{invalid conversion between ext-vector type 'float32x4_t' and 'C3DVector3'}}
+}





More information about the cfe-commits mailing list