diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 2abaadff4b..e358496f82 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1715,10 +1715,10 @@ EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) { } const Expr *condExpr = expr->getCond(); - - if (int condValue = ConstantFoldsToSimpleInteger(condExpr)) { + bool CondExprBool; + if (ConstantFoldsToSimpleInteger(condExpr, CondExprBool)) { const Expr *live = expr->getTrueExpr(), *dead = expr->getFalseExpr(); - if (condValue == -1) std::swap(live, dead); + if (!CondExprBool) std::swap(live, dead); if (!ContainsLabel(dead)) return EmitLValue(live); diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 3e1debd820..6e558e7a6b 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -2257,8 +2257,9 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { // If we have 0 && RHS, see if we can elide RHS, if so, just return 0. // If we have 1 && X, just emit X without inserting the control flow. - if (int Cond = CGF.ConstantFoldsToSimpleInteger(E->getLHS())) { - if (Cond == 1) { // If we have 1 && X, just emit X. + bool LHSCondVal; + if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) { + if (LHSCondVal) { // If we have 1 && X, just emit X. Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); // ZExt result to int or bool. return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "land.ext"); @@ -2309,8 +2310,9 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { // If we have 1 || RHS, see if we can elide RHS, if so, just return 1. // If we have 0 || X, just emit X without inserting the control flow. - if (int Cond = CGF.ConstantFoldsToSimpleInteger(E->getLHS())) { - if (Cond == -1) { // If we have 0 || X, just emit X. + bool LHSCondVal; + if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) { + if (!LHSCondVal) { // If we have 0 || X, just emit X. Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); // ZExt result to int or bool. return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "lor.ext"); @@ -2409,9 +2411,10 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { // If the condition constant folds and can be elided, try to avoid emitting // the condition and the dead arm. - if (int Cond = CGF.ConstantFoldsToSimpleInteger(condExpr)){ + bool CondExprBool; + if (CGF.ConstantFoldsToSimpleInteger(condExpr, CondExprBool)) { Expr *live = lhsExpr, *dead = rhsExpr; - if (Cond == -1) std::swap(live, dead); + if (!CondExprBool) std::swap(live, dead); // If the dead side doesn't have labels we need, and if the Live side isn't // the gnu missing ?: extension (which we could handle, but don't bother diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index cd238112ed..1ed7c3d911 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -359,10 +359,12 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { // If the condition constant folds and can be elided, try to avoid emitting // the condition and the dead arm of the if/else. - if (int Cond = ConstantFoldsToSimpleInteger(S.getCond())) { + bool CondConstant; + if (ConstantFoldsToSimpleInteger(S.getCond(), CondConstant)) { // Figure out which block (then or else) is executed. - const Stmt *Executed = S.getThen(), *Skipped = S.getElse(); - if (Cond == -1) // Condition false? + const Stmt *Executed = S.getThen(); + const Stmt *Skipped = S.getElse(); + if (!CondConstant) // Condition false? std::swap(Executed, Skipped); // If the skipped block has no labels in it, just emit the executed block. diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index f1b72863ca..ca478707ef 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -408,22 +408,23 @@ bool CodeGenFunction::ContainsLabel(const Stmt *S, bool IgnoreCaseStmts) { } -/// ConstantFoldsToSimpleInteger - If the sepcified expression does not fold to -/// a constant, or if it does but contains a label, return 0. If it constant -/// folds to 'true' and does not contain a label, return 1, if it constant folds -/// to 'false' and does not contain a label, return -1. -int CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond) { +/// ConstantFoldsToSimpleInteger - If the specified expression does not fold +/// to a constant, or if it does but contains a label, return false. If it +/// constant folds return true and set the boolean result in Result. +bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond, + bool &ResultBool) { // FIXME: Rename and handle conversion of other evaluatable things // to bool. Expr::EvalResult Result; if (!Cond->Evaluate(Result, getContext()) || !Result.Val.isInt() || Result.HasSideEffects) - return 0; // Not foldable, not integer or not fully evaluatable. + return false; // Not foldable, not integer or not fully evaluatable. if (CodeGenFunction::ContainsLabel(Cond)) - return 0; // Contains a label. + return false; // Contains a label. - return Result.Val.getInt().getBoolValue() ? 1 : -1; + ResultBool = Result.Val.getInt().getBoolValue(); + return true; } @@ -442,14 +443,17 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, if (CondBOp->getOpcode() == BO_LAnd) { // If we have "1 && X", simplify the code. "0 && X" would have constant // folded if the case was simple enough. - if (ConstantFoldsToSimpleInteger(CondBOp->getLHS()) == 1) { + bool ConstantBool; + if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) && + ConstantBool) { // br(1 && X) -> br(X). return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); } // If we have "X && 1", simplify the code to use an uncond branch. // "X && 0" would have been constant folded to 0. - if (ConstantFoldsToSimpleInteger(CondBOp->getRHS()) == 1) { + if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) && + ConstantBool) { // br(X && 1) -> br(X). return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock); } @@ -468,17 +472,22 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, eval.end(*this); return; - } else if (CondBOp->getOpcode() == BO_LOr) { + } + + if (CondBOp->getOpcode() == BO_LOr) { // If we have "0 || X", simplify the code. "1 || X" would have constant // folded if the case was simple enough. - if (ConstantFoldsToSimpleInteger(CondBOp->getLHS()) == -1) { + bool ConstantBool; + if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) && + !ConstantBool) { // br(0 || X) -> br(X). return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); } // If we have "X || 0", simplify the code to use an uncond branch. // "X || 1" would have been constant folded to 1. - if (ConstantFoldsToSimpleInteger(CondBOp->getRHS()) == -1) { + if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) && + !ConstantBool) { // br(X || 0) -> br(X). return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock); } diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index be646fb290..7a94b92fbb 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -2045,10 +2045,9 @@ public: static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts = false); /// ConstantFoldsToSimpleInteger - If the specified expression does not fold - /// to a constant, or if it does but contains a label, return 0. If it - /// constant folds to 'true' and does not contain a label, return 1, if it - /// constant folds to 'false' and does not contain a label, return -1. - int ConstantFoldsToSimpleInteger(const Expr *Cond); + /// to a constant, or if it does but contains a label, return false. If it + /// constant folds return true and set the boolean result in Result. + bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result); /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an /// if statement) to the specified blocks. Based on the condition, this might