From: Eric Botcazou Date: Fri, 17 May 2002 06:11:29 +0000 (+0000) Subject: fold-const.c (fold): Move the transformation of a comparison against the highest... X-Git-Tag: releases/gcc-3.1.1~345 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e0ad0ac4f99a13fd6d1a5cdbbf311d0c484cea1c;p=thirdparty%2Fgcc.git fold-const.c (fold): Move the transformation of a comparison against the highest or lowest integer... * 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. From-SVN: r53543 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4558ab9205ea..afeb064da3e3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2002-05-15 Eric Botcazou + + * 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. + 2002-05-16 Richard Henderson PR c/3467 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 216999861263..98e81aa75268 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -6490,7 +6490,125 @@ 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))) + switch (TREE_CODE (t)) + { + case LE_EXPR: + return fold (build (GE_EXPR, type, + convert (signed_type (TREE_TYPE (arg0)), + arg0), + convert (signed_type (TREE_TYPE (arg1)), + integer_zero_node))); + case GT_EXPR: + return fold (build (LT_EXPR, type, + convert (signed_type (TREE_TYPE (arg0)), + arg0), + convert (signed_type (TREE_TYPE (arg1)), + integer_zero_node))); + + default: + break; + } + + 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 >= CST to X > (CST - 1) and X < CST to X <= (CST - 1) + if CST is positive. */ if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) != INTEGER_CST && tree_int_cst_sgn (arg1) > 0) @@ -6514,6 +6632,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. */ @@ -6702,152 +6849,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))) - switch (TREE_CODE (t)) - { - case LE_EXPR: - return fold (build (GE_EXPR, type, - convert (signed_type (TREE_TYPE (arg0)), - arg0), - convert (signed_type (TREE_TYPE (arg1)), - integer_zero_node))); - case GT_EXPR: - return fold (build (LT_EXPR, type, - convert (signed_type (TREE_TYPE (arg0)), - arg0), - convert (signed_type (TREE_TYPE (arg1)), - integer_zero_node))); - - default: - break; - } - - 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