diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp index 87d9fc3442b34bcfac52276fe60a0e5ffef24874..23e9e980c568d22b013a7909977b187e4386ed4a 100644 --- a/lib/AST/APValue.cpp +++ b/lib/AST/APValue.cpp @@ -91,7 +91,9 @@ void APValue::print(llvm::raw_ostream &OS) const { OS << "Float: " << GetApproxValue(getFloat()); return; case Vector: - OS << "Vector: <todo>"; + OS << "Vector: " << getVectorElt(0); + for (unsigned i = 1; i != getVectorLength(); ++i) + OS << ", " << getVectorElt(i); return; case ComplexInt: OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag(); diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 4dd06b924a2bced92ce8b012529309eb919db642..03b49499ee286f8ecad2c2969bad7e1927f198e3 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -487,6 +487,7 @@ Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const { // An assignment expression [...] is not an lvalue. return LV_InvalidExpression; } + // FIXME: OverloadExprClass case CallExprClass: case CXXOperatorCallExprClass: case CXXMemberCallExprClass: { @@ -701,6 +702,10 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const { break; case StringLiteralClass: return true; + case CompoundLiteralExprClass: { + const Expr *Exp = cast<CompoundLiteralExpr>(this)->getInitializer(); + return Exp->isConstantExpr(Ctx, Loc); + } case InitListExprClass: { const InitListExpr *Exp = cast<InitListExpr>(this); unsigned numInits = Exp->getNumInits(); diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index b5a234c50806217f1c60f54dedcb38dbfdfba9f9..f45bd787b569b6b41733b0335fd766f150afaff7 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -317,6 +317,78 @@ APValue PointerExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) { return APValue(); } +//===----------------------------------------------------------------------===// +// Vector Evaluation +//===----------------------------------------------------------------------===// + +namespace { + class VISIBILITY_HIDDEN VectorExprEvaluator + : public StmtVisitor<VectorExprEvaluator, APValue> { + EvalInfo &Info; + public: + + VectorExprEvaluator(EvalInfo &info) : Info(info) {} + + APValue VisitStmt(Stmt *S) { + return APValue(); + } + + APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } + APValue VisitCastExpr(const CastExpr* E); + APValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); + APValue VisitInitListExpr(const InitListExpr *E); + }; +} // end anonymous namespace + +static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) { + if (!E->getType()->isVectorType()) + return false; + Result = VectorExprEvaluator(Info).Visit(const_cast<Expr*>(E)); + return !Result.isUninit(); +} + +APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) { + const Expr* SE = E->getSubExpr(); + + // Check for vector->vector bitcast. + if (SE->getType()->isVectorType()) + return this->Visit(const_cast<Expr*>(SE)); + + return APValue(); +} + +APValue +VectorExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { + return this->Visit(const_cast<Expr*>(E->getInitializer())); +} + +APValue +VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) { + const VectorType *VT = E->getType()->getAsVectorType(); + unsigned NumInits = E->getNumInits(); + + if (!VT || VT->getNumElements() != NumInits) + return APValue(); + + QualType EltTy = VT->getElementType(); + llvm::SmallVector<APValue, 4> Elements; + + for (unsigned i = 0; i < NumInits; i++) { + if (EltTy->isIntegerType()) { + llvm::APSInt sInt(32); + if (!EvaluateInteger(E->getInit(i), sInt, Info)) + return APValue(); + Elements.push_back(APValue(sInt)); + } else { + llvm::APFloat f(0.0); + if (!EvaluateFloat(E->getInit(i), f, Info)) + return APValue(); + Elements.push_back(APValue(f)); + } + } + return APValue(&Elements[0], Elements.size()); +} + //===----------------------------------------------------------------------===// // Integer Evaluation //===----------------------------------------------------------------------===// @@ -1067,6 +1139,7 @@ bool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) { bool FloatExprEvaluator::VisitCastExpr(CastExpr *E) { Expr* SubExpr = E->getSubExpr(); + const llvm::fltSemantics& destSemantics = Info.Ctx.getFloatTypeSemantics(E->getType()); if (SubExpr->getType()->isIntegralType()) { @@ -1189,7 +1262,10 @@ APValue ComplexFloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) bool Expr::Evaluate(EvalResult &Result, ASTContext &Ctx) const { EvalInfo Info(Ctx, Result); - if (getType()->isIntegerType()) { + if (getType()->isVectorType()) { + if (!EvaluateVector(this, Result.Val, Info)) + return false; + } else if (getType()->isIntegerType()) { llvm::APSInt sInt(32); if (!EvaluateInteger(this, sInt, Info)) return false; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 82c8ea099d19ec760064e7145d994fbacf19528a..cff01c6530129ee1b002d900a40431e456094b6c 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2187,11 +2187,9 @@ bool Sema::CheckArithmeticConstantExpression(const Expr* Init) { } bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) { - Expr::EvalResult Result; - Init = Init->IgnoreParens(); - if (Init->Evaluate(Result, Context) && !Result.HasSideEffects) + if (Init->isEvaluatable(Context)) return false; // Look through CXXDefaultArgExprs; they have no meaning in this context. diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 7d08132cd6e646df65ce8bbfd919c1158d1fd803..2bc6ff2f12f6bc0cbbe5b1e8042c05005e33e7a7 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2925,13 +2925,14 @@ QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex, 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) { + if (TypeSize == Context.getTypeSize(Context.IntTy)) return Context.getExtVectorType(Context.IntTy, VTy->getNumElements()); - } - assert(TypeSize == 64 && "Unhandled vector element size in vector compare"); + else if (TypeSize == Context.getTypeSize(Context.LongTy)) + return Context.getExtVectorType(Context.LongTy, VTy->getNumElements()); + + assert(TypeSize == Context.getTypeSize(Context.LongLongTy) && + "Unhandled vector element size in vector compare"); return Context.getExtVectorType(Context.LongLongTy, VTy->getNumElements()); } diff --git a/test/CodeGen/ext-vector.c b/test/CodeGen/ext-vector.c index ae877edb815d42106067f23674cfc61326dfc4b8..0a57397d7cdd8f42e6f16ce5b9f1b405351bad80 100644 --- a/test/CodeGen/ext-vector.c +++ b/test/CodeGen/ext-vector.c @@ -6,6 +6,8 @@ typedef __attribute__(( ext_vector_type(4) )) int int4; float4 foo = (float4){ 1.0, 2.0, 3.0, 4.0 }; +const float4 bar = (float4){ 1.0, 2.0, 3.0, __builtin_inff() }; + float4 test1(float4 V) { return V.wzyx+V; }