summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorStephen Canon <scanon@apple.com>2014-04-03 10:33:25 +0000
committerStephen Canon <scanon@apple.com>2014-04-03 10:33:25 +0000
commit3ba640d7aef9fb3f9be143853a48d44053f0b5f3 (patch)
tree8379cf16daaa6ee22bfc26094f437e5cc7c576a3 /clang/lib/Sema/SemaExpr.cpp
parent5b06f2754518cfd3046e5293be5b45907f918971 (diff)
downloadbcm5719-llvm-3ba640d7aef9fb3f9be143853a48d44053f0b5f3.tar.gz
bcm5719-llvm-3ba640d7aef9fb3f9be143853a48d44053f0b5f3.zip
Improved semantics for implicit scalar -> extvector conversions.
llvm-svn: 205521
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp63
1 files changed, 34 insertions, 29 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index f0e0485e231..7894682efcf 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -6696,35 +6696,40 @@ QualType Sema::InvalidOperands(SourceLocation Loc, ExprResult &LHS,
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(Sema &S, ExprResult *scalar,
// 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(ExprResult &LHS, ExprResult &RHS,
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(ExprResult &LHS, ExprResult &RHS,
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.
OpenPOWER on IntegriCloud