diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-06-13 06:26:32 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-06-13 06:26:32 +0000 |
| commit | 8889a3d3b5154d7d5bd4e58ab10d3df503544742 (patch) | |
| tree | 1874ac82de907ae6b2bf655a55359b9281762a43 /clang/lib | |
| parent | 27ef14f098798c4b9c89b71cbf5ad5dda8983c40 (diff) | |
| download | bcm5719-llvm-8889a3d3b5154d7d5bd4e58ab10d3df503544742.tar.gz bcm5719-llvm-8889a3d3b5154d7d5bd4e58ab10d3df503544742.zip | |
Towards PR12457: constant expression evaluation support for __builtin_parity{,l,ll}, __builtin_ffs{,l,ll}, and __builtin_fpclassify.
llvm-svn: 183889
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 77 |
1 files changed, 63 insertions, 14 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 84f7bfdf82b..ad4816a24f8 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -5691,6 +5691,13 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { return Success(Val.byteSwap(), E); } + case Builtin::BI__builtin_classify_type: + return Success(EvaluateBuiltinClassifyType(E), E); + + // FIXME: BI__builtin_clrsb + // FIXME: BI__builtin_clrsbl + // FIXME: BI__builtin_clrsbll + case Builtin::BI__builtin_clz: case Builtin::BI__builtin_clzl: case Builtin::BI__builtin_clzll: { @@ -5703,6 +5710,9 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { return Success(Val.countLeadingZeros(), E); } + case Builtin::BI__builtin_constant_p: + return Success(EvaluateBuiltinConstantP(Info.Ctx, E->getArg(0)), E); + case Builtin::BI__builtin_ctz: case Builtin::BI__builtin_ctzl: case Builtin::BI__builtin_ctzll: { @@ -5715,30 +5725,65 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { return Success(Val.countTrailingZeros(), E); } - case Builtin::BI__builtin_popcount: - case Builtin::BI__builtin_popcountl: - case Builtin::BI__builtin_popcountll: { + case Builtin::BI__builtin_eh_return_data_regno: { + int Operand = E->getArg(0)->EvaluateKnownConstInt(Info.Ctx).getZExtValue(); + Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand); + return Success(Operand, E); + } + + case Builtin::BI__builtin_expect: + return Visit(E->getArg(0)); + + case Builtin::BI__builtin_ffs: + case Builtin::BI__builtin_ffsl: + case Builtin::BI__builtin_ffsll: { APSInt Val; if (!EvaluateInteger(E->getArg(0), Val, Info)) return false; - return Success(Val.countPopulation(), E); + unsigned N = Val.countTrailingZeros(); + return Success(N == Val.getBitWidth() ? 0 : N + 1, E); } - case Builtin::BI__builtin_classify_type: - return Success(EvaluateBuiltinClassifyType(E), E); + case Builtin::BI__builtin_fpclassify: { + APFloat Val(0.0); + if (!EvaluateFloat(E->getArg(5), Val, Info)) + return false; + unsigned Arg; + switch (Val.getCategory()) { + case APFloat::fcNaN: Arg = 0; break; + case APFloat::fcInfinity: Arg = 1; break; + case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2; break; + case APFloat::fcZero: Arg = 4; break; + } + return Visit(E->getArg(Arg)); + } - case Builtin::BI__builtin_constant_p: - return Success(EvaluateBuiltinConstantP(Info.Ctx, E->getArg(0)), E); + case Builtin::BI__builtin_isinf_sign: { + APFloat Val(0.0); + return EvaluateFloat(E->getArg(5), Val, Info) && + Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E); + } - case Builtin::BI__builtin_eh_return_data_regno: { - int Operand = E->getArg(0)->EvaluateKnownConstInt(Info.Ctx).getZExtValue(); - Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand); - return Success(Operand, E); + case Builtin::BI__builtin_parity: + case Builtin::BI__builtin_parityl: + case Builtin::BI__builtin_parityll: { + APSInt Val; + if (!EvaluateInteger(E->getArg(0), Val, Info)) + return false; + + return Success(Val.countPopulation() % 2, E); } - case Builtin::BI__builtin_expect: - return Visit(E->getArg(0)); + case Builtin::BI__builtin_popcount: + case Builtin::BI__builtin_popcountl: + case Builtin::BI__builtin_popcountll: { + APSInt Val; + if (!EvaluateInteger(E->getArg(0), Val, Info)) + return false; + + return Success(Val.countPopulation(), E); + } case Builtin::BIstrlen: // A call to strlen is not a constant expression. @@ -6941,6 +6986,10 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) { Result.changeSign(); return true; + // FIXME: Builtin::BI__builtin_powi + // FIXME: Builtin::BI__builtin_powif + // FIXME: Builtin::BI__builtin_powil + case Builtin::BI__builtin_copysign: case Builtin::BI__builtin_copysignf: case Builtin::BI__builtin_copysignl: { |

