diff options
author | Roger Sayle <roger@eyesopen.com> | 2006-11-01 02:56:45 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2006-11-01 02:56:45 +0000 |
commit | 682d039597faffc4ec84e7a569b93e9447b3e681 (patch) | |
tree | d9a9688ea50ffdbd59bbb3b045ca29467f5f137c /gcc | |
parent | a3a1ebb559bce23379e851067df080d9f103f55e (diff) | |
download | gcc-682d039597faffc4ec84e7a569b93e9447b3e681.zip gcc-682d039597faffc4ec84e7a569b93e9447b3e681.tar.gz gcc-682d039597faffc4ec84e7a569b93e9447b3e681.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/fold-const.c | 57 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr23470-1.c | 12 | ||||
-rw-r--r-- | gcc/tree.h | 2 |
5 files changed, 70 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bb44011..65b835a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index a822abd..a718f14 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 12e6d5d..e5457e0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gcc.dg/pr23470-1.c b/gcc/testsuite/gcc.dg/pr23470-1.c new file mode 100644 index 0000000..2ddf6f2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr23470-1.c @@ -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" } } */ @@ -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); |