re PR middle-end/23470 (a*a (for floats) is not considered always postive (-ffast-math only))

PR middle-end/23470
	* tree.h (tree_expr_nonnegative_p): Return "bool" instead of "int".
	* fold-const.c (tree_expr_nonnegative_p): Likewise.  Consider
	pow(x,y) and powi(x,y) to be nonnegative if either x is nonnegative
	or y is an even integer.

	* gcc.dg/pr23470-1.c: New test case.

From-SVN: r118355
This commit is contained in:
Roger Sayle 2006-11-01 02:56:45 +00:00 committed by Roger Sayle
parent a3a1ebb559
commit 682d039597
5 changed files with 70 additions and 14 deletions

View File

@ -1,3 +1,11 @@
2006-10-31 Roger Sayle <roger@eyesopen.com>
PR middle-end/23470
* tree.h (tree_expr_nonnegative_p): Return "bool" instead of "int".
* fold-const.c (tree_expr_nonnegative_p): Likewise. Consider
pow(x,y) and powi(x,y) to be nonnegative if either x is nonnegative
or y is an even integer.
2006-10-31 Eric Botcazou <ebotcazou@libertysurf.fr>
PR target/24071

View File

@ -12109,14 +12109,14 @@ multiple_of_p (tree type, tree top, tree bottom)
/* Return true if `t' is known to be non-negative. */
int
bool
tree_expr_nonnegative_p (tree t)
{
if (t == error_mark_node)
return 0;
return false;
if (TYPE_UNSIGNED (TREE_TYPE (t)))
return 1;
return true;
switch (TREE_CODE (t))
{
@ -12129,7 +12129,7 @@ tree_expr_nonnegative_p (tree t)
/* We can't return 1 if flag_wrapv is set because
ABS_EXPR<INT_MIN> = INT_MIN. */
if (!(flag_wrapv && INTEGRAL_TYPE_P (TREE_TYPE (t))))
return 1;
return true;
break;
case INTEGER_CST:
@ -12166,7 +12166,7 @@ tree_expr_nonnegative_p (tree t)
{
/* x * x for floating point x is always non-negative. */
if (operand_equal_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1), 0))
return 1;
return true;
return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
&& tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
}
@ -12184,7 +12184,7 @@ tree_expr_nonnegative_p (tree t)
return TYPE_PRECISION (inner1) + TYPE_PRECISION (inner2)
< TYPE_PRECISION (TREE_TYPE (t));
}
return 0;
return false;
case BIT_AND_EXPR:
case MAX_EXPR:
@ -12234,7 +12234,7 @@ tree_expr_nonnegative_p (tree t)
if (TREE_CODE (inner_type) == INTEGER_TYPE)
{
if (TYPE_UNSIGNED (inner_type))
return 1;
return true;
return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
}
}
@ -12277,7 +12277,7 @@ tree_expr_nonnegative_p (tree t)
&& TREE_OPERAND (t, 0) == temp)
return tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
return 0;
return false;
}
case CALL_EXPR:
@ -12303,12 +12303,12 @@ tree_expr_nonnegative_p (tree t)
CASE_INT_FN (BUILT_IN_PARITY):
CASE_INT_FN (BUILT_IN_POPCOUNT):
/* Always true. */
return 1;
return true;
CASE_FLT_FN (BUILT_IN_SQRT):
/* sqrt(-0.0) is -0.0. */
if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (t))))
return 1;
return true;
return tree_expr_nonnegative_p (TREE_VALUE (arglist));
CASE_FLT_FN (BUILT_IN_ASINH):
@ -12332,7 +12332,6 @@ tree_expr_nonnegative_p (tree t)
CASE_FLT_FN (BUILT_IN_LROUND):
CASE_FLT_FN (BUILT_IN_MODF):
CASE_FLT_FN (BUILT_IN_NEARBYINT):
CASE_FLT_FN (BUILT_IN_POW):
CASE_FLT_FN (BUILT_IN_RINT):
CASE_FLT_FN (BUILT_IN_ROUND):
CASE_FLT_FN (BUILT_IN_SIGNBIT):
@ -12356,6 +12355,38 @@ tree_expr_nonnegative_p (tree t)
/* True if the 2nd argument is nonnegative. */
return tree_expr_nonnegative_p (TREE_VALUE (TREE_CHAIN (arglist)));
CASE_FLT_FN (BUILT_IN_POWI):
/* True if the 1st argument is nonnegative or the second
argument is an even integer. */
if (TREE_CODE (TREE_VALUE (TREE_CHAIN (arglist))) == INTEGER_CST)
{
tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
if ((TREE_INT_CST_LOW (arg1) & 1) == 0)
return true;
}
return tree_expr_nonnegative_p (TREE_VALUE (arglist));
CASE_FLT_FN (BUILT_IN_POW):
/* True if the 1st argument is nonnegative or the second
argument is an even integer valued real. */
if (TREE_CODE (TREE_VALUE (TREE_CHAIN (arglist))) == REAL_CST)
{
REAL_VALUE_TYPE c;
HOST_WIDE_INT n;
c = TREE_REAL_CST (TREE_VALUE (TREE_CHAIN (arglist)));
n = real_to_integer (&c);
if ((n & 1) == 0)
{
REAL_VALUE_TYPE cint;
real_from_integer (&cint, VOIDmode, n,
n < 0 ? -1 : 0, 0);
if (real_identical (&c, &cint))
return true;
}
}
return tree_expr_nonnegative_p (TREE_VALUE (arglist));
default:
break;
}
@ -12366,11 +12397,11 @@ tree_expr_nonnegative_p (tree t)
default:
if (truth_value_p (TREE_CODE (t)))
/* Truth values evaluate to 0 or 1, which is nonnegative. */
return 1;
return true;
}
/* We don't know sign of `t', so be conservative and return false. */
return 0;
return false;
}
/* Return true when T is an address and is known to be nonzero.

View File

@ -1,3 +1,8 @@
2006-10-31 Roger Sayle <roger@eyesopen.com>
PR middle-end/23470
* gcc.dg/pr23470-1.c: New test case.
2006-11-01 Bernhard Fischer <aldot@gcc.gnu.org>
PR fortran/29537

View File

@ -0,0 +1,12 @@
/* PR middle-end/23470 */
/* { dg-do compile } */
/* { dg-options "-O2 -ffast-math -fdump-tree-original" } */
int f(double a, double b)
{
if (((a*a) + (b*b))<0)
link_error();
}
/* { dg-final { scan-tree-dump-times "if \\(0\\)" 1 "original" } } */
/* { dg-final { cleanup-tree-dump "original" } } */

View File

@ -3606,7 +3606,7 @@ extern HOST_WIDE_INT tree_low_cst (tree, int);
extern int tree_int_cst_msb (tree);
extern int tree_int_cst_sgn (tree);
extern int tree_int_cst_sign_bit (tree);
extern int tree_expr_nonnegative_p (tree);
extern bool tree_expr_nonnegative_p (tree);
extern bool may_negate_without_overflow_p (tree);
extern tree get_inner_array_type (tree);