@@ -2706,7 +2706,8 @@ static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E,
2706
2706
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E,
2707
2707
QualType SrcType, QualType DestType,
2708
2708
APFloat &Result) {
2709
- assert(isa<CastExpr>(E) || isa<CompoundAssignOperator>(E));
2709
+ assert(isa<CastExpr>(E) || isa<CompoundAssignOperator>(E) ||
2710
+ isa<ConvertVectorExpr>(E));
2710
2711
llvm::RoundingMode RM = getActiveRoundingMode(Info, E);
2711
2712
APFloat::opStatus St;
2712
2713
APFloat Value = Result;
@@ -10709,6 +10710,9 @@ namespace {
10709
10710
bool VisitUnaryImag(const UnaryOperator *E);
10710
10711
bool VisitBinaryOperator(const BinaryOperator *E);
10711
10712
bool VisitUnaryOperator(const UnaryOperator *E);
10713
+ bool VisitConvertVectorExpr(const ConvertVectorExpr *E);
10714
+ bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E);
10715
+
10712
10716
// FIXME: Missing: conditional operator (for GNU
10713
10717
// conditional select), shufflevector, ExtVectorElementExpr
10714
10718
};
@@ -10961,6 +10965,138 @@ bool VectorExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
10961
10965
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
10962
10966
}
10963
10967
10968
+ static bool EvaluateVectorOrLValue(APValue &Result, EvalInfo &Info,
10969
+ const Expr *E, const QualType &Type) {
10970
+ if (!Evaluate(Result, Info, E))
10971
+ return false;
10972
+
10973
+ if (Result.isLValue()) {
10974
+ // Source of the data is an lvalue; Manually handle the lvalue as if
10975
+ // it was an rvalue to get the current APValue.
10976
+ LValue LValueFound;
10977
+ LValueFound.setFrom(Info.Ctx, Result);
10978
+ if (!handleLValueToRValueConversion(Info, E, Type, LValueFound, Result)) {
10979
+ return false;
10980
+ }
10981
+ }
10982
+
10983
+ if (!Result.isVector()) {
10984
+ return false;
10985
+ }
10986
+ return true;
10987
+ }
10988
+
10989
+ static bool handleVectorConversion(EvalInfo &Info, const FPOptions FPO,
10990
+ const Expr *E, QualType SourceTy,
10991
+ QualType DestTy, APValue const &Original,
10992
+ APValue &Result) {
10993
+ if (SourceTy->isIntegerType()) {
10994
+ if (DestTy->isRealFloatingType()) {
10995
+ Result = APValue(APFloat(0.0));
10996
+ return HandleIntToFloatCast(Info, E, FPO, SourceTy, Original.getInt(),
10997
+ DestTy, Result.getFloat());
10998
+ }
10999
+ if (DestTy->isIntegerType()) {
11000
+ Result = APValue(
11001
+ HandleIntToIntCast(Info, E, DestTy, SourceTy, Original.getInt()));
11002
+ return true;
11003
+ }
11004
+ } else if (SourceTy->isRealFloatingType()) {
11005
+ if (DestTy->isRealFloatingType()) {
11006
+ Result = Original;
11007
+ return HandleFloatToFloatCast(Info, E, SourceTy, DestTy,
11008
+ Result.getFloat());
11009
+ }
11010
+ if (DestTy->isIntegerType()) {
11011
+ Result = APValue(APSInt());
11012
+ return HandleFloatToIntCast(Info, E, SourceTy, Original.getFloat(),
11013
+ DestTy, Result.getInt());
11014
+ }
11015
+ }
11016
+ return false;
11017
+ }
11018
+
11019
+ bool VectorExprEvaluator::VisitConvertVectorExpr(const ConvertVectorExpr *E) {
11020
+ APValue Source;
11021
+ QualType SourceVecType = E->getSrcExpr()->getType();
11022
+ if (!EvaluateVectorOrLValue(Source, Info, E->getSrcExpr(), SourceVecType))
11023
+ return false;
11024
+
11025
+ QualType DestTy = E->getType()->castAs<VectorType>()->getElementType();
11026
+ QualType SourceTy = SourceVecType->castAs<VectorType>()->getElementType();
11027
+
11028
+ const FPOptions FPO = E->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
11029
+
11030
+ SmallVector<APValue, 4> ResultElements;
11031
+ ResultElements.reserve(Source.getVectorLength());
11032
+ for (unsigned EltNum = 0; EltNum < Source.getVectorLength(); ++EltNum) {
11033
+ APValue Elt;
11034
+ if (!handleVectorConversion(Info, FPO, E, SourceTy, DestTy,
11035
+ Source.getVectorElt(EltNum), Elt))
11036
+ return false;
11037
+ ResultElements.push_back(std::move(Elt));
11038
+ }
11039
+
11040
+ return Success(APValue(ResultElements.data(), ResultElements.size()), E);
11041
+ }
11042
+
11043
+ static bool handleVectorShuffle(EvalInfo &Info, const ShuffleVectorExpr *E,
11044
+ QualType ElemType, APValue const &VecVal1,
11045
+ APValue const &VecVal2, unsigned EltNum,
11046
+ APValue &Result) {
11047
+ unsigned const TotalElementsInAVector = VecVal1.getVectorLength();
11048
+
11049
+ Expr const *IndexExpr = E->getExpr(2 + EltNum);
11050
+ APSInt IndexVal;
11051
+ if (!EvaluateInteger(IndexExpr, IndexVal, Info)) {
11052
+ return false;
11053
+ }
11054
+
11055
+ uint32_t index = IndexVal.getZExtValue();
11056
+ // The spec says that -1 should be treated as undef for optimizations,
11057
+ // but in constexpr we need to choose a value. We'll choose 0.
11058
+ if (index >= TotalElementsInAVector * 2) {
11059
+ index = 0;
11060
+ }
11061
+
11062
+ if (index >= TotalElementsInAVector) {
11063
+ Result = VecVal2.getVectorElt(index - TotalElementsInAVector);
11064
+ } else {
11065
+ Result = VecVal1.getVectorElt(index);
11066
+ }
11067
+ return true;
11068
+ }
11069
+
11070
+ bool VectorExprEvaluator::VisitShuffleVectorExpr(const ShuffleVectorExpr *E) {
11071
+ APValue VecVal1;
11072
+ const Expr *Vec1 = E->getExpr(0);
11073
+ if (!EvaluateVectorOrLValue(VecVal1, Info, Vec1, Vec1->getType()))
11074
+ return false;
11075
+ APValue VecVal2;
11076
+ const Expr *Vec2 = E->getExpr(1);
11077
+ if (!EvaluateVectorOrLValue(VecVal2, Info, Vec2, Vec2->getType()))
11078
+ return false;
11079
+
11080
+ VectorType const *DestVecTy = E->getType()->castAs<VectorType>();
11081
+ if (!DestVecTy) {
11082
+ return false;
11083
+ }
11084
+ QualType DestElTy = DestVecTy->getElementType();
11085
+
11086
+ auto TotalElementsInOutputVector = DestVecTy->getNumElements();
11087
+
11088
+ SmallVector<APValue, 4> ResultElements;
11089
+ ResultElements.reserve(TotalElementsInOutputVector);
11090
+ for (unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
11091
+ APValue Elt;
11092
+ if (!handleVectorShuffle(Info, E, DestElTy, VecVal1, VecVal2, EltNum, Elt))
11093
+ return false;
11094
+ ResultElements.push_back(std::move(Elt));
11095
+ }
11096
+
11097
+ return Success(APValue(ResultElements.data(), ResultElements.size()), E);
11098
+ }
11099
+
10964
11100
//===----------------------------------------------------------------------===//
10965
11101
// Array Evaluation
10966
11102
//===----------------------------------------------------------------------===//
0 commit comments