From: Nate Begeman Date: Sun, 18 Jan 2009 03:20:47 +0000 (+0000) Subject: Support evaluation of vector constant expressions, and codegen of same. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=59b5da6d853b4368b984700315adf7b37de05764;p=clang Support evaluation of vector constant expressions, and codegen of same. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62455 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp index 87d9fc3442..23e9e980c5 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: "; + 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 4dd06b924a..03b49499ee 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(this)->getInitializer(); + return Exp->isConstantExpr(Ctx, Loc); + } case InitListExprClass: { const InitListExpr *Exp = cast(this); unsigned numInits = Exp->getNumInits(); diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index b5a234c508..f45bd787b5 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 { + 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(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(SE)); + + return APValue(); +} + +APValue +VectorExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { + return this->Visit(const_cast(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 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 82c8ea099d..cff01c6530 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 7d08132cd6..2bc6ff2f12 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 ae877edb81..0a57397d7c 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; }