diff options
author | phython <phython@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-04-18 15:18:21 +0000 |
---|---|---|
committer | phython <phython@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-04-18 15:18:21 +0000 |
commit | 89a6fcda688b6ac8df4d0a70e448556b88758582 (patch) | |
tree | 9a986aa5b5fe42c3e7cb2e30a5bd0d19a609233d /gcc/fold-const.c | |
parent | 6dbbbfec3b418e6dc95f1dc60c37ba41b12cc14d (diff) | |
download | gcc-89a6fcda688b6ac8df4d0a70e448556b88758582.tar.gz |
2005-04-18 James A. Morrison <phython@gcc.gnu.org>
PR tree-optimization/20922
* fold-const.c (fold_binary): Fold X - c > X and X + c < X to false.
Fold X + c >= X and fold X - c <= X to true.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@98321 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 3899fdac381..1e1ecc1470b 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -8848,6 +8848,77 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) } } + /* Transform comparisons of the form X +- C CMP X. */ + if ((code != EQ_EXPR && code != NE_EXPR) + && (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR) + && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0) + && ((TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST + && !HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))) + || (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST + && !TYPE_UNSIGNED (TREE_TYPE (arg1)) + && !(flag_wrapv || flag_trapv)))) + { + tree arg01 = TREE_OPERAND (arg0, 1); + enum tree_code code0 = TREE_CODE (arg0); + int is_positive; + + if (TREE_CODE (arg01) == REAL_CST) + is_positive = REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg01)) ? -1 : 1; + else + is_positive = tree_int_cst_sgn (arg01); + + /* (X - c) > X becomes false. */ + if (code == GT_EXPR + && ((code0 == MINUS_EXPR && is_positive >= 0) + || (code0 == PLUS_EXPR && is_positive <= 0))) + return constant_boolean_node (0, type); + + /* Likewise (X + c) < X becomes false. */ + if (code == LT_EXPR + && ((code0 == PLUS_EXPR && is_positive >= 0) + || (code0 == MINUS_EXPR && is_positive <= 0))) + return constant_boolean_node (0, type); + + /* Convert (X - c) <= X to true. */ + if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))) + && code == LE_EXPR + && ((code0 == MINUS_EXPR && is_positive >= 0) + || (code0 == PLUS_EXPR && is_positive <= 0))) + return constant_boolean_node (1, type); + + /* Convert (X + c) >= X to true. */ + if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))) + && code == GE_EXPR + && ((code0 == PLUS_EXPR && is_positive >= 0) + || (code0 == MINUS_EXPR && is_positive <= 0))) + return constant_boolean_node (1, type); + + if (TREE_CODE (arg01) == INTEGER_CST) + { + /* Convert X + c > X and X - c < X to true for integers. */ + if (code == GT_EXPR + && ((code0 == PLUS_EXPR && is_positive > 0) + || (code0 == MINUS_EXPR && is_positive < 0))) + return constant_boolean_node (1, type); + + if (code == LT_EXPR + && ((code0 == MINUS_EXPR && is_positive > 0) + || (code0 == PLUS_EXPR && is_positive < 0))) + return constant_boolean_node (1, type); + + /* Convert X + c <= X and X - c >= X to false for integers. */ + if (code == LE_EXPR + && ((code0 == PLUS_EXPR && is_positive > 0) + || (code0 == MINUS_EXPR && is_positive < 0))) + return constant_boolean_node (0, type); + + if (code == GE_EXPR + && ((code0 == MINUS_EXPR && is_positive > 0) + || (code0 == PLUS_EXPR && is_positive < 0))) + return constant_boolean_node (0, type); + } + } + if (FLOAT_TYPE_P (TREE_TYPE (arg0))) { tree targ0 = strip_float_extensions (arg0); |