summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2014-01-04 03:31:22 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2014-01-04 03:31:22 +0000
commiteb68f6a9de3c782e93321e48422b4ac2b4f9a6be (patch)
tree77ca69ef2e5202bab9120b7cbd4f4017de685192 /clang/lib/Sema/SemaExpr.cpp
parent658eb68e82e665132e15a96a85384974de20ceef (diff)
downloadbcm5719-llvm-eb68f6a9de3c782e93321e48422b4ac2b4f9a6be.tar.gz
bcm5719-llvm-eb68f6a9de3c782e93321e48422b4ac2b4f9a6be.zip
[Sema] When checking if a bitcast is appropriate between vector types, take into
consideration the num-of-elements*width-of-element width. Disallow casts when such width is not equal between the vector types otherwise we may end up with an invalid LLVM bitcast. rdar://15722308. llvm-svn: 198474
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp39
1 files changed, 37 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index f4802792573..842e11b6d1e 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -6612,6 +6612,42 @@ QualType Sema::InvalidOperands(SourceLocation Loc, ExprResult &LHS,
return QualType();
}
+static bool areVectorOperandsLaxBitCastable(ASTContext &Ctx,
+ QualType LHSType, QualType RHSType){
+ if (!Ctx.getLangOpts().LaxVectorConversions)
+ return false;
+
+ unsigned LHSSize = Ctx.getTypeSize(LHSType);
+ unsigned RHSSize = Ctx.getTypeSize(RHSType);
+ if (LHSSize != RHSSize)
+ return false;
+
+ // For a non-power-of-2 vector ASTContext::getTypeSize returns the size
+ // rounded to the next power-of-2, but the LLVM IR type that we create
+ // is considered to have num-of-elements*width-of-element width.
+ // Make sure such width is the same between the types, otherwise we may end
+ // up with an invalid bitcast.
+ unsigned LHSIRSize, RHSIRSize;
+ if (LHSType->isVectorType()) {
+ const VectorType *Vec = LHSType->getAs<VectorType>();
+ LHSIRSize = Vec->getNumElements() *
+ Ctx.getTypeSize(Vec->getElementType());
+ } else {
+ LHSIRSize = LHSSize;
+ }
+ if (RHSType->isVectorType()) {
+ const VectorType *Vec = RHSType->getAs<VectorType>();
+ RHSIRSize = Vec->getNumElements() *
+ Ctx.getTypeSize(Vec->getElementType());
+ } else {
+ RHSIRSize = RHSSize;
+ }
+ if (LHSIRSize != RHSIRSize)
+ return false;
+
+ return true;
+}
+
QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc, bool IsCompAssign) {
if (!IsCompAssign) {
@@ -6647,8 +6683,7 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
return RHSType;
}
- if (getLangOpts().LaxVectorConversions &&
- Context.getTypeSize(LHSType) == Context.getTypeSize(RHSType)) {
+ if (areVectorOperandsLaxBitCastable(Context, LHSType, RHSType)) {
// 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.
OpenPOWER on IntegriCloud