[cfe-commits] r133737 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp test/Sema/arm-neon-types.c test/Sema/ext_vector_casts.c test/SemaCXX/vector.cpp
Eli Friedman
eli.friedman at gmail.com
Thu Jun 23 11:10:35 PDT 2011
Author: efriedma
Date: Thu Jun 23 13:10:35 2011
New Revision: 133737
URL: http://llvm.org/viewvc/llvm-project?rev=133737&view=rev
Log:
Fix Sema::CheckVectorOperands so that it doesn't try to insert a cast expression into the LHS of a compound assignment. Fixes compound assignment of various "compatible" vector types, including NEON-vector and gcc-vector types.
<rdar://problem/9640356>
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/Sema/arm-neon-types.c
cfe/trunk/test/Sema/ext_vector_casts.c
cfe/trunk/test/SemaCXX/vector.cpp
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=133737&r1=133736&r2=133737&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Jun 23 13:10:35 2011
@@ -5559,7 +5559,8 @@
SourceLocation QuestionLoc);
/// type checking for vector binary operators.
- QualType CheckVectorOperands(SourceLocation l, ExprResult &lex, ExprResult &rex);
+ QualType CheckVectorOperands(ExprResult &lex, ExprResult &rex,
+ SourceLocation Loc, bool isCompAssign);
QualType CheckVectorCompareOperands(ExprResult &lex, ExprResult &rx,
SourceLocation l, bool isRel);
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=133737&r1=133736&r2=133737&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Jun 23 13:10:35 2011
@@ -4372,7 +4372,7 @@
// Now check the two expressions.
if (LHSTy->isVectorType() || RHSTy->isVectorType())
- return CheckVectorOperands(QuestionLoc, LHS, RHS);
+ return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false);
// OpenCL: If the condition is a vector, and both operands are scalar,
// attempt to implicity convert them to the vector type to act like the
@@ -5470,7 +5470,8 @@
return QualType();
}
-QualType Sema::CheckVectorOperands(SourceLocation Loc, ExprResult &lex, ExprResult &rex) {
+QualType Sema::CheckVectorOperands(ExprResult &lex, ExprResult &rex,
+ SourceLocation Loc, bool isCompAssign) {
// For conversion purposes, we ignore any qualifiers.
// For example, "const float" and "float" are equivalent.
QualType lhsType =
@@ -5482,42 +5483,33 @@
if (lhsType == rhsType)
return lhsType;
- // 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->getAs<VectorType>()) {
- if (const VectorType *RV = rhsType->getAs<VectorType>()) {
- if (LV->getElementType() == RV->getElementType() &&
- LV->getNumElements() == RV->getNumElements()) {
- if (lhsType->isExtVectorType()) {
- rex = ImpCastExprToType(rex.take(), lhsType, CK_BitCast);
- return lhsType;
- }
-
- lex = ImpCastExprToType(lex.take(), rhsType, CK_BitCast);
- return rhsType;
- } else if (Context.getTypeSize(lhsType) ==Context.getTypeSize(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.
- rex = ImpCastExprToType(rex.take(), lhsType, CK_BitCast);
- return lhsType;
- }
- }
- }
- }
-
// Handle the case of equivalent AltiVec and GCC vector types
if (lhsType->isVectorType() && rhsType->isVectorType() &&
Context.areCompatibleVectorTypes(lhsType, rhsType)) {
- lex = ImpCastExprToType(lex.take(), rhsType, CK_BitCast);
+ if (lhsType->isExtVectorType()) {
+ rex = ImpCastExprToType(rex.take(), lhsType, CK_BitCast);
+ return lhsType;
+ }
+
+ if (!isCompAssign)
+ lex = ImpCastExprToType(lex.take(), rhsType, CK_BitCast);
return rhsType;
}
+ if (getLangOptions().LaxVectorConversions &&
+ Context.getTypeSize(lhsType) == Context.getTypeSize(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.
+ // FIXME: Should we really be allowing this?
+ rex = ImpCastExprToType(rex.take(), lhsType, CK_BitCast);
+ return lhsType;
+ }
+
// Canonicalize the ExtVector to the LHS, remember if we swapped so we can
// swap back (so that we don't reverse the inputs to a subtract, for instance.
bool swapped = false;
- if (rhsType->isExtVectorType()) {
+ if (rhsType->isExtVectorType() && !isCompAssign) {
swapped = true;
std::swap(rex, lex);
std::swap(rhsType, lhsType);
@@ -5550,6 +5542,7 @@
}
// Vectors of different size or scalar and non-ext-vector are errors.
+ if (swapped) std::swap(rex, lex);
Diag(Loc, diag::err_typecheck_vector_not_convertable)
<< lex.get()->getType() << rex.get()->getType()
<< lex.get()->getSourceRange() << rex.get()->getSourceRange();
@@ -5559,7 +5552,7 @@
QualType Sema::CheckMultiplyDivideOperands(
ExprResult &lex, ExprResult &rex, SourceLocation Loc, bool isCompAssign, bool isDiv) {
if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType())
- return CheckVectorOperands(Loc, lex, rex);
+ return CheckVectorOperands(lex, rex, Loc, isCompAssign);
QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
if (lex.isInvalid() || rex.isInvalid())
@@ -5583,7 +5576,7 @@
if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType()) {
if (lex.get()->getType()->hasIntegerRepresentation() &&
rex.get()->getType()->hasIntegerRepresentation())
- return CheckVectorOperands(Loc, lex, rex);
+ return CheckVectorOperands(lex, rex, Loc, isCompAssign);
return InvalidOperands(Loc, lex, rex);
}
@@ -5605,7 +5598,7 @@
QualType Sema::CheckAdditionOperands( // C99 6.5.6
ExprResult &lex, ExprResult &rex, SourceLocation Loc, QualType* CompLHSTy) {
if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType()) {
- QualType compType = CheckVectorOperands(Loc, lex, rex);
+ QualType compType = CheckVectorOperands(lex, rex, Loc, CompLHSTy);
if (CompLHSTy) *CompLHSTy = compType;
return compType;
}
@@ -5690,7 +5683,7 @@
QualType Sema::CheckSubtractionOperands(ExprResult &lex, ExprResult &rex,
SourceLocation Loc, QualType* CompLHSTy) {
if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType()) {
- QualType compType = CheckVectorOperands(Loc, lex, rex);
+ QualType compType = CheckVectorOperands(lex, rex, Loc, CompLHSTy);
if (CompLHSTy) *CompLHSTy = compType;
return compType;
}
@@ -5913,7 +5906,7 @@
// Vector shifts promote their scalar inputs to vector type.
if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType())
- return CheckVectorOperands(Loc, lex, rex);
+ return CheckVectorOperands(lex, rex, Loc, isCompAssign);
// Shifts don't perform usual arithmetic conversions, they just do integer
// promotions on each operand. C99 6.5.7p3
@@ -6382,7 +6375,7 @@
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);
+ QualType vType = CheckVectorOperands(lex, rex, Loc, /*isCompAssign*/false);
if (vType.isNull())
return vType;
@@ -6437,7 +6430,7 @@
if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType()) {
if (lex.get()->getType()->hasIntegerRepresentation() &&
rex.get()->getType()->hasIntegerRepresentation())
- return CheckVectorOperands(Loc, lex, rex);
+ return CheckVectorOperands(lex, rex, Loc, isCompAssign);
return InvalidOperands(Loc, lex, rex);
}
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=133737&r1=133736&r2=133737&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Jun 23 13:10:35 2011
@@ -3636,7 +3636,7 @@
// Extension: conditional operator involving vector types.
if (LTy->isVectorType() || RTy->isVectorType())
- return CheckVectorOperands(QuestionLoc, LHS, RHS);
+ return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false);
// -- The second and third operands have arithmetic or enumeration type;
// the usual arithmetic conversions are performed to bring them to a
Modified: cfe/trunk/test/Sema/arm-neon-types.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/arm-neon-types.c?rev=133737&r1=133736&r2=133737&view=diff
==============================================================================
--- cfe/trunk/test/Sema/arm-neon-types.c (original)
+++ cfe/trunk/test/Sema/arm-neon-types.c Thu Jun 23 13:10:35 2011
@@ -18,3 +18,10 @@
// removed when that is fixed.
return vcvt_n_f32_u32(x, 0); // expected-error {{argument should be a value from 1 to 32}} expected-error {{incompatible result type}}
}
+
+typedef signed int vSInt32 __attribute__((__vector_size__(16)));
+int32x4_t test4(int32x4_t a, vSInt32 b) {
+ a += b;
+ b += a;
+ return b += a;
+}
Modified: cfe/trunk/test/Sema/ext_vector_casts.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/ext_vector_casts.c?rev=133737&r1=133736&r2=133737&view=diff
==============================================================================
--- cfe/trunk/test/Sema/ext_vector_casts.c (original)
+++ cfe/trunk/test/Sema/ext_vector_casts.c Thu Jun 23 13:10:35 2011
@@ -37,7 +37,7 @@
vec4 /= 5.2f;
vec4 %= 4; // expected-error {{invalid operands to binary expression ('float4' and 'int')}}
ivec4 %= 4;
- ivec4 += vec4; // expected-error {{can't convert between vector values of different size ('float4' and 'int4')}}
+ ivec4 += vec4; // expected-error {{can't convert between vector values of different size ('int4' and 'float4')}}
ivec4 += (int4)vec4;
ivec4 -= ivec4;
ivec4 |= ivec4;
Modified: cfe/trunk/test/SemaCXX/vector.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/vector.cpp?rev=133737&r1=133736&r2=133737&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/vector.cpp (original)
+++ cfe/trunk/test/SemaCXX/vector.cpp Thu Jun 23 13:10:35 2011
@@ -176,10 +176,10 @@
(void)(to_c16 * to_c16e);
(void)(to_c16 / to_c16e);
(void)(rto_c16 = c16e); // expected-error{{no viable overloaded '='}}
- (void)(rto_c16 += to_c16e); // expected-error{{expression is not assignable}}
- (void)(rto_c16 -= to_c16e); // expected-error{{expression is not assignable}}
- (void)(rto_c16 *= to_c16e); // expected-error{{expression is not assignable}}
- (void)(rto_c16 /= to_c16e); // expected-error{{expression is not assignable}}
+ (void)(rto_c16 += to_c16e);
+ (void)(rto_c16 -= to_c16e);
+ (void)(rto_c16 *= to_c16e);
+ (void)(rto_c16 /= to_c16e);
(void)(Cond? to_c16 : to_c16e);
(void)(Cond? to_ll16e : to_ll16);
More information about the cfe-commits
mailing list