Commit 033afd11 by Richard Henderson

[multiple changes]

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.

From-SVN: r53493
parent 14285ace
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.
2002-05-15 Richard Henderson <rth@redhat.com>
* varasm.c (merge_weak): Error for any weakening after definition.
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment