diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-05-15 20:39:55 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-05-15 20:39:55 +0000 |
commit | 8539da5e0a6876c2501e5c7832a6809f3a3fc9d0 (patch) | |
tree | fb2a015f0ac63f048599d765f38276b4cc2c2f94 /gcc/fold-const.c | |
parent | b0a9f80acafd1b19f3853604805d603d6bca419b (diff) | |
download | gcc-8539da5e0a6876c2501e5c7832a6809f3a3fc9d0.tar.gz |
2002-05-15 Jakub Jelinek <jakub@redhat.com>
* fold-const.c (fold): Fix a typo.
2002-05-15 Eric Botcazou <ebotcazou@multimania.com>
* fold-const.c (fold) [LT_EXPR]: Move the transformation of a
comparison against the highest or lowest integer value before
the 'X >= CST to X > (CST - 1)' and 'X < CST to X <= (CST - 1)'
transformation and that of an unsigned comparison against 0
right after.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@53493 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 280 |
1 files changed, 140 insertions, 140 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 2a9f6c6ee7c..0744ada154d 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -5962,7 +5962,117 @@ fold (expr) } } - /* Change X >= CST to X > (CST - 1) if CST is positive. */ + /* Comparisons with the highest or lowest possible integer of + the specified size will have known values and an unsigned + <= 0x7fffffff can be simplified. */ + { + int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg1))); + + if (TREE_CODE (arg1) == INTEGER_CST + && ! TREE_CONSTANT_OVERFLOW (arg1) + && width <= HOST_BITS_PER_WIDE_INT + && (INTEGRAL_TYPE_P (TREE_TYPE (arg1)) + || POINTER_TYPE_P (TREE_TYPE (arg1)))) + { + if (TREE_INT_CST_HIGH (arg1) == 0 + && (TREE_INT_CST_LOW (arg1) + == ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1) + && ! TREE_UNSIGNED (TREE_TYPE (arg1))) + switch (TREE_CODE (t)) + { + case GT_EXPR: + return omit_one_operand (type, + convert (type, integer_zero_node), + arg0); + case GE_EXPR: + TREE_SET_CODE (t, EQ_EXPR); + break; + + case LE_EXPR: + return omit_one_operand (type, + convert (type, integer_one_node), + arg0); + case LT_EXPR: + TREE_SET_CODE (t, NE_EXPR); + break; + + default: + break; + } + + else if (TREE_INT_CST_HIGH (arg1) == -1 + && (TREE_INT_CST_LOW (arg1) + == ((unsigned HOST_WIDE_INT) -1 << (width - 1))) + && ! TREE_UNSIGNED (TREE_TYPE (arg1))) + switch (TREE_CODE (t)) + { + case LT_EXPR: + return omit_one_operand (type, + convert (type, integer_zero_node), + arg0); + case LE_EXPR: + TREE_SET_CODE (t, EQ_EXPR); + break; + + case GE_EXPR: + return omit_one_operand (type, + convert (type, integer_one_node), + arg0); + case GT_EXPR: + TREE_SET_CODE (t, NE_EXPR); + break; + + default: + break; + } + + else if (TREE_INT_CST_HIGH (arg1) == 0 + && (TREE_INT_CST_LOW (arg1) + == ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1) + && TREE_UNSIGNED (TREE_TYPE (arg1)) + /* signed_type does not work on pointer types. */ + && INTEGRAL_TYPE_P (TREE_TYPE (arg1))) + { + if (TREE_CODE (t) == LE_EXPR || TREE_CODE (t) == GT_EXPR) + { + tree st0, st1; + st0 = (*lang_hooks.types.signed_type) (TREE_TYPE (arg0)); + st1 = (*lang_hooks.types.signed_type) (TREE_TYPE (arg1)); + return fold + (build (TREE_CODE (t) == LE_EXPR ? GE_EXPR: LT_EXPR, + type, convert (st0, arg0), + convert (st1, integer_zero_node))); + } + } + else if (TREE_INT_CST_HIGH (arg1) == 0 + && (TREE_INT_CST_LOW (arg1) + == ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1) + && TREE_UNSIGNED (TREE_TYPE (arg1))) + switch (TREE_CODE (t)) + { + case GT_EXPR: + return omit_one_operand (type, + convert (type, integer_zero_node), + arg0); + case GE_EXPR: + TREE_SET_CODE (t, EQ_EXPR); + break; + + case LE_EXPR: + return omit_one_operand (type, + convert (type, integer_one_node), + arg0); + case LT_EXPR: + TREE_SET_CODE (t, NE_EXPR); + break; + + default: + break; + } + } + } + + /* Change X >= C to X > C-1 and X < C to X <= C-1 if C is positive. */ if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) != INTEGER_CST && tree_int_cst_sgn (arg1) > 0) @@ -5986,6 +6096,35 @@ fold (expr) } } + /* An unsigned comparison against 0 can be simplified. */ + if (integer_zerop (arg1) + && (INTEGRAL_TYPE_P (TREE_TYPE (arg1)) + || POINTER_TYPE_P (TREE_TYPE (arg1))) + && TREE_UNSIGNED (TREE_TYPE (arg1))) + { + switch (TREE_CODE (t)) + { + case GT_EXPR: + code = NE_EXPR; + TREE_SET_CODE (t, NE_EXPR); + break; + case LE_EXPR: + code = EQ_EXPR; + TREE_SET_CODE (t, EQ_EXPR); + break; + case GE_EXPR: + return omit_one_operand (type, + convert (type, integer_one_node), + arg0); + case LT_EXPR: + return omit_one_operand (type, + convert (type, integer_zero_node), + arg0); + default: + break; + } + } + /* If this is an EQ or NE comparison of a constant with a PLUS_EXPR or a MINUS_EXPR of a constant, we can convert it into a comparison with a revised constant as long as no overflow occurs. */ @@ -6191,145 +6330,6 @@ fold (expr) } } - /* An unsigned comparison against 0 can be simplified. */ - if (integer_zerop (arg1) - && (INTEGRAL_TYPE_P (TREE_TYPE (arg1)) - || POINTER_TYPE_P (TREE_TYPE (arg1))) - && TREE_UNSIGNED (TREE_TYPE (arg1))) - { - switch (TREE_CODE (t)) - { - case GT_EXPR: - code = NE_EXPR; - TREE_SET_CODE (t, NE_EXPR); - break; - case LE_EXPR: - code = EQ_EXPR; - TREE_SET_CODE (t, EQ_EXPR); - break; - case GE_EXPR: - return omit_one_operand (type, - convert (type, integer_one_node), - arg0); - case LT_EXPR: - return omit_one_operand (type, - convert (type, integer_zero_node), - arg0); - default: - break; - } - } - - /* Comparisons with the highest or lowest possible integer of - the specified size will have known values and an unsigned - <= 0x7fffffff can be simplified. */ - { - int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg1))); - - if (TREE_CODE (arg1) == INTEGER_CST - && ! TREE_CONSTANT_OVERFLOW (arg1) - && width <= HOST_BITS_PER_WIDE_INT - && (INTEGRAL_TYPE_P (TREE_TYPE (arg1)) - || POINTER_TYPE_P (TREE_TYPE (arg1)))) - { - if (TREE_INT_CST_HIGH (arg1) == 0 - && (TREE_INT_CST_LOW (arg1) - == ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1) - && ! TREE_UNSIGNED (TREE_TYPE (arg1))) - switch (TREE_CODE (t)) - { - case GT_EXPR: - return omit_one_operand (type, - convert (type, integer_zero_node), - arg0); - case GE_EXPR: - TREE_SET_CODE (t, EQ_EXPR); - break; - - case LE_EXPR: - return omit_one_operand (type, - convert (type, integer_one_node), - arg0); - case LT_EXPR: - TREE_SET_CODE (t, NE_EXPR); - break; - - default: - break; - } - - else if (TREE_INT_CST_HIGH (arg1) == -1 - && (TREE_INT_CST_LOW (arg1) - == ((unsigned HOST_WIDE_INT) 1 << (width - 1))) - && ! TREE_UNSIGNED (TREE_TYPE (arg1))) - switch (TREE_CODE (t)) - { - case LT_EXPR: - return omit_one_operand (type, - convert (type, integer_zero_node), - arg0); - case LE_EXPR: - TREE_SET_CODE (t, EQ_EXPR); - break; - - case GE_EXPR: - return omit_one_operand (type, - convert (type, integer_one_node), - arg0); - case GT_EXPR: - TREE_SET_CODE (t, NE_EXPR); - break; - - default: - break; - } - - else if (TREE_INT_CST_HIGH (arg1) == 0 - && (TREE_INT_CST_LOW (arg1) - == ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1) - && TREE_UNSIGNED (TREE_TYPE (arg1)) - /* signed_type does not work on pointer types. */ - && INTEGRAL_TYPE_P (TREE_TYPE (arg1))) - { - if (TREE_CODE (t) == LE_EXPR || TREE_CODE (t) == GT_EXPR) - { - tree st0, st1; - st0 = (*lang_hooks.types.signed_type) (TREE_TYPE (arg0)); - st1 = (*lang_hooks.types.signed_type) (TREE_TYPE (arg1)); - return fold - (build (TREE_CODE (t) == LE_EXPR ? GE_EXPR: LT_EXPR, - type, convert (st0, arg0), - convert (st1, integer_zero_node))); - } - } - else if (TREE_INT_CST_HIGH (arg1) == 0 - && (TREE_INT_CST_LOW (arg1) - == ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1) - && TREE_UNSIGNED (TREE_TYPE (arg1))) - switch (TREE_CODE (t)) - { - case GT_EXPR: - return omit_one_operand (type, - convert (type, integer_zero_node), - arg0); - case GE_EXPR: - TREE_SET_CODE (t, EQ_EXPR); - break; - - case LE_EXPR: - return omit_one_operand (type, - convert (type, integer_one_node), - arg0); - case LT_EXPR: - TREE_SET_CODE (t, NE_EXPR); - break; - - default: - break; - } - } - } - /* If we are comparing an expression that just has comparisons of two integer values, arithmetic expressions of those comparisons, and constants, we can simplify it. There are only three cases |