From c0b8b19bd8056d6b5d831623a0825cce150f4507 Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Wed, 1 Jul 2009 07:50:47 +0000 Subject: [PATCH] Implement Eli's feedback for vecto constant expressions; For ExtVectorType, initializer is splatted to all elements. For VectorType, initializer is bitcast to vector type. Verified that for VectorType, output is identical to gcc. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74600 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ExprConstant.cpp | 57 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 4a9c420cb9..ec2005a99f 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -485,6 +485,11 @@ static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) { } APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) { + const VectorType *VTy = E->getType()->getAsVectorType(); + QualType EltTy = VTy->getElementType(); + unsigned NElts = VTy->getNumElements(); + unsigned EltWidth = Info.Ctx.getTypeSize(EltTy); + const Expr* SE = E->getSubExpr(); QualType SETy = SE->getType(); APValue Result = APValue(); @@ -501,13 +506,55 @@ APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) { if (EvaluateFloat(SE, F, Info)) Result = APValue(F); } + + if (!Result.isInt() && Result.isFloat()) + return APValue(); + + // For casts of a scalar to ExtVector, convert the scalar to the element type + // and splat it to all elements. + if (E->getType()->isExtVectorType()) { + if (EltTy->isIntegerType() && Result.isInt()) + Result = APValue(HandleIntToIntCast(EltTy, SETy, Result.getInt(), + Info.Ctx)); + else if (EltTy->isIntegerType()) + Result = APValue(HandleFloatToIntCast(EltTy, SETy, Result.getFloat(), + Info.Ctx)); + else if (EltTy->isRealFloatingType() && Result.isInt()) + Result = APValue(HandleIntToFloatCast(EltTy, SETy, Result.getInt(), + Info.Ctx)); + else if (EltTy->isRealFloatingType()) + Result = APValue(HandleFloatToFloatCast(EltTy, SETy, Result.getFloat(), + Info.Ctx)); + else + return APValue(); - if (Result.isInt() || Result.isFloat()) { - unsigned NumElts = E->getType()->getAsVectorType()->getNumElements(); - llvm::SmallVector Elts(NumElts, Result); - Result = APValue(&Elts[0], Elts.size()); + // Splat and create vector APValue. + llvm::SmallVector Elts(NElts, Result); + return APValue(&Elts[0], Elts.size()); } - return Result; + + // For casts of a scalar to regular gcc-style vector type, bitcast the scalar + // to the vector. To construct the APValue vector initializer, bitcast the + // initializing value to an APInt, and shift out the bits pertaining to each + // element. + APSInt Init; + Init = Result.isInt() ? Result.getInt() : Result.getFloat().bitcastToAPInt(); + + llvm::SmallVector Elts; + for (unsigned i = 0; i != NElts; ++i) { + APSInt Tmp = Init; + Tmp.extOrTrunc(EltWidth); + + if (EltTy->isIntegerType()) + Elts.push_back(APValue(Tmp)); + else if (EltTy->isRealFloatingType()) + Elts.push_back(APValue(APFloat(Tmp))); + else + return APValue(); + + Init >>= EltWidth; + } + return APValue(&Elts[0], Elts.size()); } APValue -- 2.40.0