summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-11-12 07:04:29 +0000
committerChris Lattner <sabre@nondot.org>2008-11-12 07:04:29 +0000
commitaa3f951efcdb4715632edb3227b847056eccbeec (patch)
treeba978d67e99fe82d6f6df45a3016b921074335c1 /clang/lib/AST/ExprConstant.cpp
parent4b6c7efbde9f6e757e5d4f26688c3a8c0e00e568 (diff)
downloadbcm5719-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.cpp22
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;
OpenPOWER on IntegriCloud