summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2008-07-14 18:02:46 +0000
committerNate Begeman <natebegeman@mac.com>2008-07-14 18:02:46 +0000
commit191a6b1f1bf9d8c8e1e26735fc1059f2f002f103 (patch)
tree5fb698f45942d79b54840535b1da42e9b69d6677 /clang/lib/Sema
parent162668fa7836ec6fdde9d24216a4d0198d10c5cf (diff)
downloadbcm5719-llvm-191a6b1f1bf9d8c8e1e26735fc1059f2f002f103.tar.gz
bcm5719-llvm-191a6b1f1bf9d8c8e1e26735fc1059f2f002f103.zip
http://llvm.org/bugs/show_bug.cgi?id=2523
Add some code to handle vector comparisons, which is the language side of the llvm vicmp/vfcmp instructions. Also make the vector-vector and vector-scalar asign checks a bit more sane under the presence of lax vector conversions. llvm-svn: 53565
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/Sema.h6
-rw-r--r--clang/lib/Sema/SemaExpr.cpp104
2 files changed, 88 insertions, 22 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index 9df94d4ae40..c19daded7c3 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -812,7 +812,6 @@ private:
/// type checking binary operators (subroutines of ActOnBinOp).
inline QualType InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex);
- inline QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex);
inline QualType CheckMultiplyDivideOperands( // C99 6.5.5
Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
inline QualType CheckRemainderOperands( // C99 6.5.5
@@ -838,6 +837,11 @@ private:
Expr *&lex, Expr *&rex, SourceLocation OpLoc);
inline QualType CheckConditionalOperands( // C99 6.5.15
Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
+
+ /// type checking for vector binary operators.
+ inline QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex);
+ inline QualType CheckVectorCompareOperands(Expr *&lex, Expr *&rx,
+ SourceLocation l, bool isRel);
/// type checking unary operators (subroutines of ActOnUnaryOp).
/// C99 6.5.3.1, 6.5.3.2, 6.5.3.4
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 71f7717e5d8..7e3319a9427 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -1370,24 +1370,19 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
return Incompatible;
}
- if (isa<VectorType>(lhsType) || isa<VectorType>(rhsType)) {
+ if (lhsType->isVectorType() || rhsType->isVectorType()) {
// For ExtVector, allow vector splats; float -> <n x float>
- if (const ExtVectorType *LV = dyn_cast<ExtVectorType>(lhsType)) {
- if (LV->getElementType().getTypePtr() == rhsType.getTypePtr())
+ if (const ExtVectorType *LV = lhsType->getAsExtVectorType())
+ if (LV->getElementType() == rhsType)
return Compatible;
- }
- // If LHS and RHS are both vectors of integer or both vectors of floating
- // point types, and the total vector length is the same, allow the
- // conversion. This is a bitcast; no bits are changed but the result type
- // is different.
+ // 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.
if (getLangOptions().LaxVectorConversions &&
lhsType->isVectorType() && rhsType->isVectorType()) {
- if ((lhsType->isIntegerType() && rhsType->isIntegerType()) ||
- (lhsType->isRealFloatingType() && rhsType->isRealFloatingType())) {
- if (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType))
- return Compatible;
- }
+ if (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType))
+ return Compatible;
}
return Incompatible;
}
@@ -1472,25 +1467,40 @@ inline QualType Sema::CheckVectorOperands(SourceLocation loc, Expr *&lex,
QualType lhsType = lex->getType().getCanonicalType().getUnqualifiedType();
QualType rhsType = rex->getType().getCanonicalType().getUnqualifiedType();
- // make sure the vector types are identical.
+ // If the vector types are identical, return.
if (lhsType == rhsType)
return lhsType;
- // if the lhs is an extended vector and the rhs is a scalar of the same type,
- // promote the rhs to the vector type.
+ // Handle the case of a vector & extvector type of the same size and element
+ // type. It would be nice if we only had one vector type someday.
+ if (getLangOptions().LaxVectorConversions)
+ if (const VectorType *LV = lhsType->getAsVectorType())
+ if (const VectorType *RV = rhsType->getAsVectorType())
+ if (LV->getElementType() == RV->getElementType() &&
+ LV->getNumElements() == RV->getNumElements())
+ return lhsType->isExtVectorType() ? lhsType : rhsType;
+
+ // If the lhs is an extended vector and the rhs is a scalar of the same type
+ // or a literal, promote the rhs to the vector type.
if (const ExtVectorType *V = lhsType->getAsExtVectorType()) {
- if (V->getElementType().getCanonicalType().getTypePtr()
- == rhsType.getCanonicalType().getTypePtr()) {
+ QualType eltType = V->getElementType();
+
+ if ((eltType->getAsBuiltinType() == rhsType->getAsBuiltinType()) ||
+ (eltType->isIntegerType() && isa<IntegerLiteral>(rex)) ||
+ (eltType->isFloatingType() && isa<FloatingLiteral>(rex))) {
ImpCastExprToType(rex, lhsType);
return lhsType;
}
}
- // if the rhs is an extended vector and the lhs is a scalar of the same type,
+ // If the rhs is an extended vector and the lhs is a scalar of the same type,
// promote the lhs to the vector type.
if (const ExtVectorType *V = rhsType->getAsExtVectorType()) {
- if (V->getElementType().getCanonicalType().getTypePtr()
- == lhsType.getCanonicalType().getTypePtr()) {
+ QualType eltType = V->getElementType();
+
+ if ((eltType->getAsBuiltinType() == lhsType->getAsBuiltinType()) ||
+ (eltType->isIntegerType() && isa<IntegerLiteral>(lex)) ||
+ (eltType->isFloatingType() && isa<FloatingLiteral>(lex))) {
ImpCastExprToType(lex, rhsType);
return rhsType;
}
@@ -1656,6 +1666,9 @@ QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation loc,
// C99 6.5.8
QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation loc,
bool isRelational) {
+ if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
+ return CheckVectorCompareOperands(lex, rex, loc, isRelational);
+
// C99 6.5.8p3 / C99 6.5.9p4
if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType())
UsualArithmeticConversions(lex, rex);
@@ -1740,6 +1753,55 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation loc,
return InvalidOperands(loc, lex, rex);
}
+/// CheckVectorCompareOperands - vector comparisons are a clang extension that
+/// operates on extended vector types. Instead of producing an IntTy result,
+/// like a scalar comparison, a vector comparison produces a vector of integer
+/// types.
+QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex,
+ SourceLocation loc,
+ bool isRelational) {
+ // Check to make sure we're operating on vectors of the same type and width,
+ // Allowing one side to be a scalar of element type.
+ QualType vType = CheckVectorOperands(loc, lex, rex);
+ if (vType.isNull())
+ return vType;
+
+ QualType lType = lex->getType();
+ QualType rType = rex->getType();
+
+ // For non-floating point types, check for self-comparisons of the form
+ // x == x, x != x, x < x, etc. These always evaluate to a constant, and
+ // often indicate logic errors in the program.
+ if (!lType->isFloatingType()) {
+ if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(lex->IgnoreParens()))
+ if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(rex->IgnoreParens()))
+ if (DRL->getDecl() == DRR->getDecl())
+ Diag(loc, diag::warn_selfcomparison);
+ }
+
+ // Check for comparisons of floating point operands using != and ==.
+ if (!isRelational && lType->isFloatingType()) {
+ assert (rType->isFloatingType());
+ CheckFloatComparison(loc,lex,rex);
+ }
+
+ // Return the type for the comparison, which is the same as vector type for
+ // integer vectors, or an integer type of identical size and number of
+ // elements for floating point vectors.
+ if (lType->isIntegerType())
+ return lType;
+
+ const VectorType *VTy = lType->getAsVectorType();
+
+ // FIXME: need to deal with non-32b int / non-64b long long
+ unsigned TypeSize = Context.getTypeSize(VTy->getElementType());
+ if (TypeSize == 32) {
+ return Context.getExtVectorType(Context.IntTy, VTy->getNumElements());
+ }
+ assert(TypeSize == 64 && "Unhandled vector element size in vector compare");
+ return Context.getExtVectorType(Context.LongLongTy, VTy->getNumElements());
+}
+
inline QualType Sema::CheckBitwiseOperands(
Expr *&lex, Expr *&rex, SourceLocation loc, bool isCompAssign)
{
OpenPOWER on IntegriCloud