Teach the aggressive constant folder to fold X && 0 -> 0 and X || 1 -> 1

llvm-svn: 59105
This commit is contained in:
Chris Lattner 2008-11-12 07:04:29 +00:00
parent 4b6c7efbde
commit aa3f951efc
1 changed files with 21 additions and 1 deletions

View File

@ -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;