diff options
author | Zdenek Dvorak <dvorakz@suse.cz> | 2007-02-09 14:29:11 +0100 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2007-02-09 13:29:11 +0000 |
commit | b44e7f07c5a8b8dfe7549583d3504f1a39208b03 (patch) | |
tree | a7c503e98956c6e5d624c17e6ed753cc613964aa /gcc/fold-const.c | |
parent | 917fbceb1b9687c2871b1ca1074389287339d06a (diff) | |
download | gcc-b44e7f07c5a8b8dfe7549583d3504f1a39208b03.zip gcc-b44e7f07c5a8b8dfe7549583d3504f1a39208b03.tar.gz gcc-b44e7f07c5a8b8dfe7549583d3504f1a39208b03.tar.bz2 |
re PR tree-optimization/23361 (Can't eliminate empty loops with power of two step and variable bounds)
2007-02-09 Zdenek Dvorak <dvorakz@suse.cz>
Richard Guenther <rguenther@suse.de>
PR middle-end/23361
* fold-const.c (fold_comparison): Handle obfuscated comparisons
against INT_MIN/INT_MAX.
* tree-ssa-loop-ivcanon.c (remove_empty_loop): Print to dump
file if a loop is removed.
* gcc.dg/fold-compare-3.c: New testcase.
* gcc.dg/tree-ssa/loop-24.c: Likewise.
Co-Authored-By: Richard Guenther <rguenther@suse.de>
From-SVN: r121742
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 0b37a0f..d20d78f 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -8043,6 +8043,40 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1) lhs = fold_build2 (lhs_add ? PLUS_EXPR : MINUS_EXPR, TREE_TYPE (arg1), const2, const1); + + /* If the constant operation overflowed this can be + simplified as a comparison against INT_MAX/INT_MIN. */ + if (TREE_CODE (lhs) == INTEGER_CST + && TREE_OVERFLOW (lhs)) + { + int const1_sgn = tree_int_cst_sgn (const1); + enum tree_code code2 = code; + + /* Get the sign of the constant on the lhs if the + operation were VARIABLE + CONST1. */ + if (TREE_CODE (arg0) == MINUS_EXPR) + const1_sgn = -const1_sgn; + + /* The sign of the constant determines if we overflowed + INT_MAX (const1_sgn == -1) or INT_MIN (const1_sgn == 1). + Canonicalize to the INT_MIN overflow by swapping the comparison + if necessary. */ + if (const1_sgn == -1) + code2 = swap_tree_comparison (code); + + /* We now can look at the canonicalized case + VARIABLE + 1 CODE2 INT_MIN + and decide on the result. */ + if (code2 == LT_EXPR + || code2 == LE_EXPR + || code2 == EQ_EXPR) + return omit_one_operand (type, boolean_false_node, variable); + else if (code2 == NE_EXPR + || code2 == GE_EXPR + || code2 == GT_EXPR) + return omit_one_operand (type, boolean_true_node, variable); + } + if (TREE_CODE (lhs) == TREE_CODE (arg1) && (TREE_CODE (lhs) != INTEGER_CST || !TREE_OVERFLOW (lhs))) |