diff options
author | kan <kan@FreeBSD.org> | 2002-09-01 20:38:57 +0000 |
---|---|---|
committer | kan <kan@FreeBSD.org> | 2002-09-01 20:38:57 +0000 |
commit | 2e25f3a6c57335cba50111faceb0ce2ab59e9bcb (patch) | |
tree | c6857d31c36dbd89a881b0229bf38b062797d413 /contrib/gcc/fold-const.c | |
parent | 0895e1acb698e05d503c26bec5471de2e88b7d93 (diff) | |
download | FreeBSD-src-2e25f3a6c57335cba50111faceb0ce2ab59e9bcb.zip FreeBSD-src-2e25f3a6c57335cba50111faceb0ce2ab59e9bcb.tar.gz |
Gcc 3.2.1-prerelease from the FSF anoncvs repo gcc-3_2-branch on 1-Sep-2002 00:00:01 EDT.
Diffstat (limited to 'contrib/gcc/fold-const.c')
-rw-r--r-- | contrib/gcc/fold-const.c | 314 |
1 files changed, 160 insertions, 154 deletions
diff --git a/contrib/gcc/fold-const.c b/contrib/gcc/fold-const.c index 2169998..a7e1e28 100644 --- a/contrib/gcc/fold-const.c +++ b/contrib/gcc/fold-const.c @@ -4515,17 +4515,22 @@ extract_muldiv (t, c, code, wide_type) break; case CONVERT_EXPR: case NON_LVALUE_EXPR: case NOP_EXPR: - /* If op0 is an expression, and is unsigned, and the type is - smaller than ctype, then we cannot widen the expression. */ + /* If op0 is an expression... */ if ((TREE_CODE_CLASS (TREE_CODE (op0)) == '<' || TREE_CODE_CLASS (TREE_CODE (op0)) == '1' || TREE_CODE_CLASS (TREE_CODE (op0)) == '2' || TREE_CODE_CLASS (TREE_CODE (op0)) == 'e') - && TREE_UNSIGNED (TREE_TYPE (op0)) - && ! (TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE - && TYPE_IS_SIZETYPE (TREE_TYPE (op0))) - && (GET_MODE_SIZE (TYPE_MODE (ctype)) - > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0))))) + /* ...and is unsigned, and its type is smaller than ctype, + then we cannot pass through this widening. */ + && ((TREE_UNSIGNED (TREE_TYPE (op0)) + && ! (TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE + && TYPE_IS_SIZETYPE (TREE_TYPE (op0))) + && (GET_MODE_SIZE (TYPE_MODE (ctype)) + > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0))))) + /* ...and its type is larger than ctype, + then we cannot pass through this truncation. */ + || (GET_MODE_SIZE (TYPE_MODE (ctype)) + < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))))) break; /* Pass the constant down and see if we can make a simplification. If @@ -6490,7 +6495,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 +6637,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 +6854,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 |