diff options
author | Daniel Dunbar <daniel@zuster.org> | 2008-10-16 03:51:50 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2008-10-16 03:51:50 +0000 |
commit | 5db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afb (patch) | |
tree | 15a37364326fcef126fcbf59b036bce17e39e0ed /lib/AST/ExprConstant.cpp | |
parent | 3b0db908ebd07eaa26bc90deba5e826de00fe515 (diff) |
Teach tryEvaluate that fabs, copysign, and unary +/- are constants for
floats.
- With testcase, which also has some other things GCC folds but we
don't commented out in it.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57624 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index cc2b4e6735..5bc4170e70 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -586,6 +586,7 @@ public: bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } bool VisitCallExpr(const CallExpr *E); + bool VisitUnaryOperator(const UnaryOperator *E); bool VisitBinaryOperator(const BinaryOperator *E); bool VisitFloatingLiteral(const FloatingLiteral *E); }; @@ -625,14 +626,48 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) { } } return false; + + case Builtin::BI__builtin_fabs: + case Builtin::BI__builtin_fabsf: + case Builtin::BI__builtin_fabsl: + if (!EvaluateFloat(E->getArg(0), Result, Info)) + return false; + + if (Result.isNegative()) + Result.changeSign(); + return true; + + case Builtin::BI__builtin_copysign: + case Builtin::BI__builtin_copysignf: + case Builtin::BI__builtin_copysignl: { + APFloat RHS(0.); + if (!EvaluateFloat(E->getArg(0), Result, Info) || + !EvaluateFloat(E->getArg(1), RHS, Info)) + return false; + Result.copySign(RHS); + return true; + } } } +bool FloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { + if (!EvaluateFloat(E->getSubExpr(), Result, Info)) + return false; + + switch (E->getOpcode()) { + default: return false; + case UnaryOperator::Plus: + return true; + case UnaryOperator::Minus: + Result.changeSign(); + return true; + } +} bool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { // FIXME: Diagnostics? I really don't understand how the warnings // and errors are supposed to work. - APFloat LHS(0.0), RHS(0.0); + APFloat RHS(0.0); if (!EvaluateFloat(E->getLHS(), Result, Info)) return false; if (!EvaluateFloat(E->getRHS(), RHS, Info)) |