mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-30 11:15:21 +08:00
[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
This commit is contained in:
parent
14285ace88
commit
033afd1106
@ -1,3 +1,15 @@
|
||||
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.
|
||||
|
280
gcc/fold-const.c
280
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
|
||||
|
Loading…
Reference in New Issue
Block a user