r205521 - Improved semantics for implicit scalar -> extvector conversions.
Stephen Canon
scanon at apple.com
Thu Apr 3 03:33:25 PDT 2014
Author: scanon
Date: Thu Apr 3 05:33:25 2014
New Revision: 205521
URL: http://llvm.org/viewvc/llvm-project?rev=205521&view=rev
Log:
Improved semantics for implicit scalar -> extvector conversions.
Modified:
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/Sema/ext_vector_casts.c
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=205521&r1=205520&r2=205521&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Thu Apr 3 05:33:25 2014
@@ -5780,6 +5780,8 @@ void CheckImplicitConversion(Sema &S, Ex
Source = cast<VectorType>(Source)->getElementType().getTypePtr();
Target = cast<VectorType>(Target)->getElementType().getTypePtr();
}
+ if (auto VecTy = dyn_cast<VectorType>(Target))
+ Target = VecTy->getElementType().getTypePtr();
// Strip complex types.
if (isa<ComplexType>(Source)) {
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=205521&r1=205520&r2=205521&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Apr 3 05:33:25 2014
@@ -6696,35 +6696,40 @@ QualType Sema::InvalidOperands(SourceLoc
return QualType();
}
-/// 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.
+/// Try to convert a value of non-vector type to a vector type by converting
+/// the type to the element type of the vector and then performing a splat.
+/// If the language is OpenCL, we only use conversions that promote scalar
+/// rank; for C, Obj-C, and C++ we allow any real scalar conversion except
+/// for float->int.
///
/// \param scalar - if non-null, actually perform the conversions
/// \return true if the operation fails (but without diagnosing the failure)
-static bool tryVectorPromoteAndSplat(Sema &S, ExprResult *scalar,
+static bool tryVectorConvertAndSplat(Sema &S, ExprResult *scalar,
QualType scalarTy,
QualType vectorEltTy,
QualType vectorTy) {
// The conversion to apply to the scalar before splatting it,
// if necessary.
CastKind scalarCast = CK_Invalid;
-
+
if (vectorEltTy->isIntegralType(S.Context)) {
- if (!scalarTy->isIntegralType(S.Context)) return true;
- int order = S.Context.getIntegerTypeOrder(vectorEltTy, scalarTy);
- if (order < 0) return true;
- if (order > 0) scalarCast = CK_IntegralCast;
+ if (!scalarTy->isIntegralType(S.Context))
+ return true;
+ if (S.getLangOpts().OpenCL &&
+ S.Context.getIntegerTypeOrder(vectorEltTy, scalarTy) < 0)
+ return true;
+ scalarCast = CK_IntegralCast;
} else if (vectorEltTy->isRealFloatingType()) {
if (scalarTy->isRealFloatingType()) {
- int order = S.Context.getFloatingTypeOrder(vectorEltTy, scalarTy);
- if (order < 0) return true;
- if (order > 0) scalarCast = CK_FloatingCast;
- } else if (scalarTy->isIntegralType(S.Context)) {
+ if (S.getLangOpts().OpenCL &&
+ S.Context.getFloatingTypeOrder(vectorEltTy, scalarTy) < 0)
+ return true;
+ scalarCast = CK_FloatingCast;
+ }
+ else if (scalarTy->isIntegralType(S.Context))
scalarCast = CK_IntegralToFloating;
- } else {
+ else
return true;
- }
} else {
return true;
}
@@ -6732,7 +6737,7 @@ static bool tryVectorPromoteAndSplat(Sem
// Adjust scalar if desired.
if (scalar) {
if (scalarCast != CK_Invalid)
- *scalar = S.ImpCastExprToType(scalar->take(), vectorEltTy, scalarCast);
+ *scalar = S.ImpCastExprToType(scalar->take(), vectorEltTy, scalarCast);
*scalar = S.ImpCastExprToType(scalar->take(), vectorTy, CK_VectorSplat);
}
return false;
@@ -6775,6 +6780,19 @@ QualType Sema::CheckVectorOperands(ExprR
return RHSType;
}
+ // If there's an ext-vector type and a scalar, try to convert the scalar to
+ // the vector element type and splat.
+ if (!RHSVecType && isa<ExtVectorType>(LHSVecType)) {
+ if (!tryVectorConvertAndSplat(*this, &RHS, RHSType,
+ LHSVecType->getElementType(), LHSType))
+ return LHSType;
+ }
+ if (!LHSVecType && isa<ExtVectorType>(RHSVecType)) {
+ if (!tryVectorConvertAndSplat(*this, (IsCompAssign ? 0 : &LHS), LHSType,
+ RHSVecType->getElementType(), RHSType))
+ return RHSType;
+ }
+
// If we're allowing lax vector conversions, only the total (data) size
// needs to be the same.
// FIXME: Should we really be allowing this?
@@ -6785,19 +6803,6 @@ QualType Sema::CheckVectorOperands(ExprR
return resultType;
}
- // If there's an ext-vector type and a scalar, try to promote (and
- // only promote) and splat the scalar to the vector type.
- if (!RHSVecType && isa<ExtVectorType>(LHSVecType)) {
- if (!tryVectorPromoteAndSplat(*this, &RHS, RHSType,
- LHSVecType->getElementType(), LHSType))
- return LHSType;
- }
- if (!LHSVecType && isa<ExtVectorType>(RHSVecType)) {
- if (!tryVectorPromoteAndSplat(*this, (IsCompAssign ? 0 : &LHS), LHSType,
- RHSVecType->getElementType(), RHSType))
- return RHSType;
- }
-
// Okay, the expression is invalid.
// If there's a non-vector, non-real operand, diagnose that.
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=205521&r1=205520&r2=205521&view=diff
==============================================================================
--- cfe/trunk/test/Sema/ext_vector_casts.c (original)
+++ cfe/trunk/test/Sema/ext_vector_casts.c Thu Apr 3 05:33:25 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -fsyntax-only -verify -fno-lax-vector-conversions %s
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -fsyntax-only -verify -fno-lax-vector-conversions -Wconversion %s
typedef __attribute__(( ext_vector_type(2) )) float float2;
typedef __attribute__(( ext_vector_type(3) )) float float3;
@@ -38,9 +38,8 @@ static void test() {
ivec4 = (int4)ptr; // expected-error {{invalid conversion between vector type 'int4' and scalar type 'int *'}}
vec4 = (float4)vec2; // expected-error {{invalid conversion between ext-vector type 'float4' and 'float2'}}
-
- ish8 += 5; // expected-error {{can't convert between vector values of different size ('short8' and 'int')}}
- ish8 += (short)5;
+
+ ish8 += 5;
ivec4 *= 5;
vec4 /= 5.2f;
vec4 %= 4; // expected-error {{invalid operands to binary expression ('float4' and 'int')}}
@@ -89,3 +88,37 @@ extern float32x4_t vabsq_f32(float32x4_t
C3DVector3 Func(const C3DVector3 a) {
return (C3DVector3)vabsq_f32((float32x4_t)a); // expected-error {{invalid conversion between ext-vector type 'float32x4_t' and 'C3DVector3'}}
}
+
+// rdar://16350802
+typedef double double2 __attribute__ ((ext_vector_type(2)));
+
+static void splats(int i, long l, __uint128_t t, float f, double d) {
+ short8 vs = 0;
+ int4 vi = i;
+ ulong2 vl = (unsigned long)l;
+ float2 vf = f;
+ double2 vd = d;
+
+ vs = 65536 + vs; // expected-warning {{implicit conversion from 'int' to 'short8' changes value from 65536 to 0}}
+ vs = vs + i; // expected-warning {{implicit conversion loses integer precision}}
+ vs = vs + 1;
+ vs = vs + 1.f; // expected-error {{can't convert between vector values of different size}}
+
+ vi = l + vi; // expected-warning {{implicit conversion loses integer precision}}
+ vi = 1 + vi;
+ vi = vi + 2.0; // expected-error {{can't convert between vector values of different size}}
+ vi = vi + 0xffffffff; // expected-warning {{implicit conversion changes signedness}}
+
+ vl = l + vl; // expected-warning {{implicit conversion changes signedness}}
+ vl = vl + t; // expected-warning {{implicit conversion loses integer precision}}
+
+ vf = 1 + vf;
+ vf = l + vf;
+ vf = 2.0 + vf;
+ vf = d + vf; // expected-warning {{implicit conversion loses floating-point precision}}
+ vf = vf + 0xffffffff;
+ vf = vf + 2.1; // expected-warning {{implicit conversion loses floating-point precision}}
+
+ vd = l + vd;
+ vd = vd + t;
+}
More information about the cfe-commits
mailing list