summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-06-13 06:26:32 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-06-13 06:26:32 +0000
commit8889a3d3b5154d7d5bd4e58ab10d3df503544742 (patch)
tree1874ac82de907ae6b2bf655a55359b9281762a43 /clang/lib
parent27ef14f098798c4b9c89b71cbf5ad5dda8983c40 (diff)
downloadbcm5719-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.cpp77
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: {
OpenPOWER on IntegriCloud