diff options
author | Chris Lattner <sabre@nondot.org> | 2008-11-12 07:04:29 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-11-12 07:04:29 +0000 |
commit | c8cc9ccc7b87a7ed1749b074f6b670bcec49abc1 (patch) | |
tree | 87adfd6d2f614e11eca91abdd0467cb0041eb85c /lib/AST/ExprConstant.cpp | |
parent | 746e03ed511664a1c781b209faaa3a66d4593480 (diff) |
Teach the aggressive constant folder to fold X && 0 -> 0 and X || 1 -> 1
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59105 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 99fa8d5813..e2be9f16e5 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -323,8 +323,28 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { // The LHS of a constant expr is always evaluated and needed. llvm::APSInt RHS(32); - if (!Visit(E->getLHS())) + if (!Visit(E->getLHS())) { + // If the LHS is unfoldable, we generally can't fold this. However, if this + // is a logical operator like &&/||, and if we know that the RHS determines + // the outcome of the result (e.g. X && 0), return the outcome. + if (!E->isLogicalOp()) + return false; + + // If this is a logical op, see if the RHS determines the outcome. + EvalInfo Info2(Info.Ctx); + if (!EvaluateInteger(E->getRHS(), RHS, Info2)) + return false; + + // X && 0 -> 0, X || 1 -> 1. + if (E->getOpcode() == BinaryOperator::LAnd && RHS == 0 || + E->getOpcode() == BinaryOperator::LOr && RHS != 0) { + Result = RHS != 0; + Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); + return true; + } + return false; // error in subexpression. + } bool OldEval = Info.isEvaluated; |