[cfe-commits] r53565 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaExpr.cpp test/Sema/vector-assign.c
Nate Begeman
natebegeman at mac.com
Mon Jul 14 11:02:47 PDT 2008
Author: sampo
Date: Mon Jul 14 13:02:46 2008
New Revision: 53565
URL: http://llvm.org/viewvc/llvm-project?rev=53565&view=rev
Log:
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.
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/Sema/vector-assign.c
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=53565&r1=53564&r2=53565&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Jul 14 13:02:46 2008
@@ -812,7 +812,6 @@
/// 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 @@
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
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=53565&r1=53564&r2=53565&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jul 14 13:02:46 2008
@@ -1370,24 +1370,19 @@
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 @@
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 @@
// 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 @@
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)
{
Modified: cfe/trunk/test/Sema/vector-assign.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vector-assign.c?rev=53565&r1=53564&r2=53565&view=diff
==============================================================================
--- cfe/trunk/test/Sema/vector-assign.c (original)
+++ cfe/trunk/test/Sema/vector-assign.c Mon Jul 14 13:02:46 2008
@@ -14,12 +14,12 @@
v1 = v2;
v1 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v2s'}}
- v1 = v4; // expected-error {{incompatible type assigning 'v2f', expected 'v2s'}}
+ v1 = v4;
v1 = v5;
v2 = v1;
v2 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v2u'}}
- v2 = v4; // expected-error {{incompatible type assigning 'v2f', expected 'v2u'}}
+ v2 = v4;
v2 = v5;
v3 = v1; // expected-error {{incompatible type assigning 'v2s', expected 'v1s'}}
@@ -27,15 +27,15 @@
v3 = v4; // expected-error {{incompatible type assigning 'v2f', expected 'v1s'}}
v3 = v5; // expected-error {{incompatible type assigning 'v4ss', expected 'v1s'}}
- v4 = v1; // expected-error {{incompatible type assigning 'v2s', expected 'v2f'}}
- v4 = v2; // expected-error {{incompatible type assigning 'v2u', expected 'v2f'}}
+ v4 = v1;
+ v4 = v2;
v4 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v2f'}}
- v4 = v5; // expected-error {{incompatible type assigning 'v4ss', expected 'v2f'}}
+ v4 = v5;
v5 = v1;
v5 = v2;
v5 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v4ss'}}
- v5 = v4; // expected-error {{incompatible type assigning 'v2f', expected 'v4ss'}}
+ v5 = v4;
}
// PR2263
More information about the cfe-commits
mailing list