mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-15 15:50:31 +08:00
re PR middle-end/168 (Spurious signed/unsigned comparison warning)
PR middle-end/168 * fold-const.c (tree_expr_nonnegative_p): Handle addition and multiplication of zero extensions, floating point division, and integer<->fp, fp<->fp and zero extension conversions. The built-in ceil and floor functions preserve signedness. * gcc.dg/20030612-1.c: New test case. From-SVN: r67850
This commit is contained in:
parent
6356f89288
commit
96f26e4161
@ -1,3 +1,11 @@
|
||||
2003-06-12 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
PR middle-end/168
|
||||
* fold-const.c (tree_expr_nonnegative_p): Handle addition
|
||||
and multiplication of zero extensions, floating point division,
|
||||
and integer<->fp, fp<->fp and zero extension conversions.
|
||||
The built-in ceil and floor functions preserve signedness.
|
||||
|
||||
2003-06-12 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
* ChangeLog: Follow spelling conventions.
|
||||
|
@ -8022,9 +8022,27 @@ tree_expr_nonnegative_p (t)
|
||||
return ! REAL_VALUE_NEGATIVE (TREE_REAL_CST (t));
|
||||
|
||||
case PLUS_EXPR:
|
||||
return FLOAT_TYPE_P (TREE_TYPE (t))
|
||||
&& tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
|
||||
&& tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
|
||||
if (FLOAT_TYPE_P (TREE_TYPE (t)))
|
||||
return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
|
||||
&& tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
|
||||
|
||||
/* zero_extend(x) + zero_extend(y) is non-negative is x and y are
|
||||
both unsigned and at atleast 2 bits shorter than the result. */
|
||||
if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
|
||||
&& TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (t, 1)) == NOP_EXPR)
|
||||
{
|
||||
tree inner1 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0));
|
||||
tree inner2 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0));
|
||||
if (TREE_CODE (inner1) == INTEGER_TYPE && TREE_UNSIGNED (inner1)
|
||||
&& TREE_CODE (inner2) == INTEGER_TYPE && TREE_UNSIGNED (inner2))
|
||||
{
|
||||
unsigned int prec = MAX (TYPE_PRECISION (inner1),
|
||||
TYPE_PRECISION (inner2)) + 1;
|
||||
return prec < TYPE_PRECISION (TREE_TYPE (t));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MULT_EXPR:
|
||||
if (FLOAT_TYPE_P (TREE_TYPE (t)))
|
||||
@ -8035,6 +8053,20 @@ tree_expr_nonnegative_p (t)
|
||||
return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
|
||||
&& tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
|
||||
}
|
||||
|
||||
/* zero_extend(x) * zero_extend(y) is non-negative is x and y are
|
||||
both unsigned and their total bits is shorter than the result. */
|
||||
if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
|
||||
&& TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (t, 1)) == NOP_EXPR)
|
||||
{
|
||||
tree inner1 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0));
|
||||
tree inner2 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0));
|
||||
if (TREE_CODE (inner1) == INTEGER_TYPE && TREE_UNSIGNED (inner1)
|
||||
&& TREE_CODE (inner2) == INTEGER_TYPE && TREE_UNSIGNED (inner2))
|
||||
return TYPE_PRECISION (inner1) + TYPE_PRECISION (inner2)
|
||||
< TYPE_PRECISION (TREE_TYPE (t));
|
||||
}
|
||||
return 0;
|
||||
|
||||
case TRUNC_DIV_EXPR:
|
||||
@ -8042,12 +8074,45 @@ tree_expr_nonnegative_p (t)
|
||||
case FLOOR_DIV_EXPR:
|
||||
case ROUND_DIV_EXPR:
|
||||
return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
|
||||
&& tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
|
||||
&& tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
|
||||
|
||||
case TRUNC_MOD_EXPR:
|
||||
case CEIL_MOD_EXPR:
|
||||
case FLOOR_MOD_EXPR:
|
||||
case ROUND_MOD_EXPR:
|
||||
return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
|
||||
|
||||
case RDIV_EXPR:
|
||||
return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
|
||||
&& tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
|
||||
|
||||
case NOP_EXPR:
|
||||
{
|
||||
tree inner_type = TREE_TYPE (TREE_OPERAND (t, 0));
|
||||
tree outer_type = TREE_TYPE (t);
|
||||
|
||||
if (TREE_CODE (outer_type) == REAL_TYPE)
|
||||
{
|
||||
if (TREE_CODE (inner_type) == REAL_TYPE)
|
||||
return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
|
||||
if (TREE_CODE (inner_type) == INTEGER_TYPE)
|
||||
{
|
||||
if (TREE_UNSIGNED (inner_type))
|
||||
return 1;
|
||||
return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (outer_type) == INTEGER_TYPE)
|
||||
{
|
||||
if (TREE_CODE (inner_type) == REAL_TYPE)
|
||||
return tree_expr_nonnegative_p (TREE_OPERAND (t,0));
|
||||
if (TREE_CODE (inner_type) == INTEGER_TYPE)
|
||||
return TYPE_PRECISION (inner_type) < TYPE_PRECISION (outer_type)
|
||||
&& TREE_UNSIGNED (inner_type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case COND_EXPR:
|
||||
return tree_expr_nonnegative_p (TREE_OPERAND (t, 1))
|
||||
&& tree_expr_nonnegative_p (TREE_OPERAND (t, 2));
|
||||
@ -8097,6 +8162,12 @@ tree_expr_nonnegative_p (t)
|
||||
case BUILT_IN_ATAN:
|
||||
case BUILT_IN_ATANF:
|
||||
case BUILT_IN_ATANL:
|
||||
case BUILT_IN_CEIL:
|
||||
case BUILT_IN_CEILF:
|
||||
case BUILT_IN_CEILL:
|
||||
case BUILT_IN_FLOOR:
|
||||
case BUILT_IN_FLOORF:
|
||||
case BUILT_IN_FLOORL:
|
||||
return tree_expr_nonnegative_p (TREE_VALUE (arglist));
|
||||
|
||||
case BUILT_IN_POW:
|
||||
@ -8115,10 +8186,10 @@ tree_expr_nonnegative_p (t)
|
||||
if (truth_value_p (TREE_CODE (t)))
|
||||
/* Truth values evaluate to 0 or 1, which is nonnegative. */
|
||||
return 1;
|
||||
else
|
||||
/* We don't know sign of `t', so be conservative and return false. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We don't know sign of `t', so be conservative and return false. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return true if `r' is known to be non-negative.
|
||||
|
@ -1,3 +1,8 @@
|
||||
2003-06-12 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
PR middle-end/168
|
||||
* gcc.dg/20030612-1.c: New test case.
|
||||
|
||||
2003-06-12 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/10635
|
||||
|
20
gcc/testsuite/gcc.dg/20030612-1.c
Normal file
20
gcc/testsuite/gcc.dg/20030612-1.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Derived from PR middle-end/168. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-W" } */
|
||||
|
||||
extern void foo ();
|
||||
|
||||
unsigned char uc;
|
||||
unsigned short int usi;
|
||||
unsigned int ui;
|
||||
|
||||
|
||||
void bar()
|
||||
{
|
||||
if (uc + usi >= ui) /* { dg-bogus "between signed and unsigned" } */
|
||||
foo ();
|
||||
if (uc * usi >= ui) /* { dg-bogus "between signed and unsigned" } */
|
||||
foo ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user