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 | aa3f951efcdb4715632edb3227b847056eccbeec (patch) | |
tree | ba978d67e99fe82d6f6df45a3016b921074335c1 /clang/lib/AST/ExprConstant.cpp | |
parent | 4b6c7efbde9f6e757e5d4f26688c3a8c0e00e568 (diff) | |
download | bcm5719-llvm-aa3f951efcdb4715632edb3227b847056eccbeec.tar.gz bcm5719-llvm-aa3f951efcdb4715632edb3227b847056eccbeec.zip |
Teach the aggressive constant folder to fold X && 0 -> 0 and X || 1 -> 1
llvm-svn: 59105
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 99fa8d5813d..e2be9f16e5e 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/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; |