fold-const.c (fold_binary): Use the precision of the type instead of the size of its mode to compute the...

* fold-const.c (fold_binary) <LT_EXPR>: Use the precision of the
	type instead of the size of its mode to compute the highest and
	lowest possible values.  Still check the size of the mode before
	flipping the signedness of the comparison.

From-SVN: r119422
This commit is contained in:
Eric Botcazou 2006-12-01 22:46:45 +00:00 committed by Eric Botcazou
parent 09aad82b44
commit f0dbdfbb4d
2 changed files with 26 additions and 14 deletions

View File

@ -1,3 +1,10 @@
2006-12-01 Eric Botcazou <ebotcazou@adacore.com>
* fold-const.c (fold_binary) <LT_EXPR>: Use the precision of the
type instead of the size of its mode to compute the highest and
lowest possible values. Still check the size of the mode before
flipping the signedness of the comparison.
2006-12-01 Trevor Smigiel <trevor_smigiel@playstation.sony.com>
* config/spu/predicates.md (spu_mov_operand): Add.

View File

@ -7758,24 +7758,24 @@ fold_minmax (enum tree_code code, tree type, tree op0, tree op1)
else
gcc_unreachable ();
/* MIN (MAX (a, b), b) == b.  */
/* MIN (MAX (a, b), b) == b. */
if (TREE_CODE (op0) == compl_code
&& operand_equal_p (TREE_OPERAND (op0, 1), op1, 0))
return omit_one_operand (type, op1, TREE_OPERAND (op0, 0));
/* MIN (MAX (b, a), b) == b.  */
/* MIN (MAX (b, a), b) == b. */
if (TREE_CODE (op0) == compl_code
&& operand_equal_p (TREE_OPERAND (op0, 0), op1, 0)
&& reorder_operands_p (TREE_OPERAND (op0, 1), op1))
return omit_one_operand (type, op1, TREE_OPERAND (op0, 1));
/* MIN (a, MAX (a, b)) == a.  */
/* MIN (a, MAX (a, b)) == a. */
if (TREE_CODE (op1) == compl_code
&& operand_equal_p (op0, TREE_OPERAND (op1, 0), 0)
&& reorder_operands_p (op0, TREE_OPERAND (op1, 1)))
return omit_one_operand (type, op0, TREE_OPERAND (op1, 1));
/* MIN (a, MAX (b, a)) == a.  */
/* MIN (a, MAX (b, a)) == a. */
if (TREE_CODE (op1) == compl_code
&& operand_equal_p (op0, TREE_OPERAND (op1, 1), 0)
&& reorder_operands_p (op0, TREE_OPERAND (op1, 0)))
@ -10994,15 +10994,15 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
}
/* Comparisons with the highest or lowest possible integer of
the specified size will have known values. */
the specified precision will have known values. */
{
int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg1)));
tree arg1_type = TREE_TYPE (arg1);
unsigned int width = TYPE_PRECISION (arg1_type);
if (TREE_CODE (arg1) == INTEGER_CST
&& ! TREE_CONSTANT_OVERFLOW (arg1)
&& width <= 2 * HOST_BITS_PER_WIDE_INT
&& (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
|| POINTER_TYPE_P (TREE_TYPE (arg1))))
&& (INTEGRAL_TYPE_P (arg1_type) || POINTER_TYPE_P (arg1_type)))
{
HOST_WIDE_INT signed_max_hi;
unsigned HOST_WIDE_INT signed_max_lo;
@ -11015,7 +11015,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
signed_max_hi = 0;
max_hi = 0;
if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
if (TYPE_UNSIGNED (arg1_type))
{
max_lo = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
min_lo = 0;
@ -11037,7 +11037,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
max_lo = -1;
min_lo = 0;
if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
if (TYPE_UNSIGNED (arg1_type))
{
max_hi = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
min_hi = 0;
@ -11124,9 +11124,14 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
else if (TREE_INT_CST_HIGH (arg1) == signed_max_hi
&& TREE_INT_CST_LOW (arg1) == signed_max_lo
&& TYPE_UNSIGNED (TREE_TYPE (arg1))
&& TYPE_UNSIGNED (arg1_type)
/* We will flip the signedness of the comparison operator
associated with the mode of arg1, so the sign bit is
specified by this mode. Check that arg1 is the signed
max associated with this sign bit. */
&& width == GET_MODE_BITSIZE (TYPE_MODE (arg1_type))
/* signed_type does not work on pointer types. */
&& INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
&& INTEGRAL_TYPE_P (arg1_type))
{
/* The following case also applies to X < signed_max+1
and X >= signed_max+1 because previous transformations. */
@ -11136,8 +11141,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
st0 = lang_hooks.types.signed_type (TREE_TYPE (arg0));
st1 = lang_hooks.types.signed_type (TREE_TYPE (arg1));
return fold_build2 (code == LE_EXPR ? GE_EXPR: LT_EXPR,
type, fold_convert (st0, arg0),
build_int_cst (st1, 0));
type, fold_convert (st0, arg0),
build_int_cst (st1, 0));
}
}
}