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