summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/fold-const.c
diff options
context:
space:
mode:
authorkan <kan@FreeBSD.org>2002-09-01 20:38:57 +0000
committerkan <kan@FreeBSD.org>2002-09-01 20:38:57 +0000
commit2e25f3a6c57335cba50111faceb0ce2ab59e9bcb (patch)
treec6857d31c36dbd89a881b0229bf38b062797d413 /contrib/gcc/fold-const.c
parent0895e1acb698e05d503c26bec5471de2e88b7d93 (diff)
downloadFreeBSD-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.c314
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
OpenPOWER on IntegriCloud