diff options
author | Sameer Sahasrabuddhe <sameer@sbuddhe.net> | 2015-02-25 05:48:23 +0000 |
---|---|---|
committer | Sameer Sahasrabuddhe <sameer@sbuddhe.net> | 2015-02-25 05:48:23 +0000 |
commit | a75db66eee43652d80e54e457ca2cc64c49c7bd4 (patch) | |
tree | df033752c3251f4804319439df6ca98732a6abe7 /clang/lib/Sema | |
parent | e20ede26d2122ef22462ad6612c3db4039ccba08 (diff) | |
download | bcm5719-llvm-a75db66eee43652d80e54e457ca2cc64c49c7bd4.tar.gz bcm5719-llvm-a75db66eee43652d80e54e457ca2cc64c49c7bd4.zip |
Restores r228382, which was reverted in r228406.
The original commit failed to handle "shift assign" (<<=), which
broke the test mentioned in r228406. This is now fixed and the
test added to the lit tests under SemaOpenCL.
*** Original commit message from r228382 ***
OpenCL: handle shift operator with vector operands
Introduce a number of checks:
1. If LHS is a scalar, then RHS cannot be a vector.
2. Operands must be of integer type.
3. If both are vectors, then the number of elements must match.
Relax the requirement for "usual arithmetic conversions":
When LHS is a vector, a scalar RHS can simply be expanded into a
vector; OpenCL does not require that its rank be lower than the LHS.
For example, the following code is not an error even if the implicit
type of the constant literal is "int".
char2 foo(char2 v) { return v << 1; }
Consolidate existing tests under CodeGenOpenCL, and add more tests
under SemaOpenCL.
llvm-svn: 230464
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 90f50465826..1b2af7d0133 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7779,6 +7779,69 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS, << RHS.get()->getSourceRange(); } +/// \brief Return the resulting type when an OpenCL vector is shifted +/// by a scalar or vector shift amount. +static QualType checkOpenCLVectorShift(Sema &S, + ExprResult &LHS, ExprResult &RHS, + SourceLocation Loc, bool IsCompAssign) { + // OpenCL v1.1 s6.3.j says RHS can be a vector only if LHS is a vector. + if (!LHS.get()->getType()->isVectorType()) { + S.Diag(Loc, diag::err_shift_rhs_only_vector) + << RHS.get()->getType() << LHS.get()->getType() + << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); + return QualType(); + } + + if (!IsCompAssign) { + LHS = S.UsualUnaryConversions(LHS.get()); + if (LHS.isInvalid()) return QualType(); + } + + RHS = S.UsualUnaryConversions(RHS.get()); + if (RHS.isInvalid()) return QualType(); + + QualType LHSType = LHS.get()->getType(); + const VectorType *LHSVecTy = LHSType->getAs<VectorType>(); + QualType LHSEleType = LHSVecTy->getElementType(); + + // Note that RHS might not be a vector. + QualType RHSType = RHS.get()->getType(); + const VectorType *RHSVecTy = RHSType->getAs<VectorType>(); + QualType RHSEleType = RHSVecTy ? RHSVecTy->getElementType() : RHSType; + + // OpenCL v1.1 s6.3.j says that the operands need to be integers. + if (!LHSEleType->isIntegerType()) { + S.Diag(Loc, diag::err_typecheck_expect_int) + << LHS.get()->getType() << LHS.get()->getSourceRange(); + return QualType(); + } + + if (!RHSEleType->isIntegerType()) { + S.Diag(Loc, diag::err_typecheck_expect_int) + << RHS.get()->getType() << RHS.get()->getSourceRange(); + return QualType(); + } + + if (RHSVecTy) { + // OpenCL v1.1 s6.3.j says that for vector types, the operators + // are applied component-wise. So if RHS is a vector, then ensure + // that the number of elements is the same as LHS... + if (RHSVecTy->getNumElements() != LHSVecTy->getNumElements()) { + S.Diag(Loc, diag::err_typecheck_vector_lengths_not_equal) + << LHS.get()->getType() << RHS.get()->getType() + << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); + return QualType(); + } + } else { + // ...else expand RHS to match the number of elements in LHS. + QualType VecTy = + S.Context.getExtVectorType(RHSEleType, LHSVecTy->getNumElements()); + RHS = S.ImpCastExprToType(RHS.get(), VecTy, CK_VectorSplat); + } + + return LHSType; +} + // C99 6.5.7 QualType Sema::CheckShiftOperands(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc, @@ -7787,8 +7850,11 @@ QualType Sema::CheckShiftOperands(ExprResult &LHS, ExprResult &RHS, // Vector shifts promote their scalar inputs to vector type. if (LHS.get()->getType()->isVectorType() || - RHS.get()->getType()->isVectorType()) + RHS.get()->getType()->isVectorType()) { + if (LangOpts.OpenCL) + return checkOpenCLVectorShift(*this, LHS, RHS, Loc, IsCompAssign); return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign); + } // Shifts don't perform usual arithmetic conversions, they just do integer // promotions on each operand. C99 6.5.7p3 |