summaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2002-05-15 20:39:55 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2002-05-15 20:39:55 +0000
commit8539da5e0a6876c2501e5c7832a6809f3a3fc9d0 (patch)
treefb2a015f0ac63f048599d765f38276b4cc2c2f94 /gcc/fold-const.c
parentb0a9f80acafd1b19f3853604805d603d6bca419b (diff)
downloadgcc-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.c280
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