OSDN Git Service

PR middle-end/23470
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Nov 2006 02:56:45 +0000 (02:56 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Nov 2006 02:56:45 +0000 (02:56 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@118355 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr23470-1.c [new file with mode: 0644]
gcc/tree.h

index bb44011..65b835a 100644 (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
index a822abd..a718f14 100644 (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.
index 12e6d5d..e5457e0 100644 (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
diff --git a/gcc/testsuite/gcc.dg/pr23470-1.c b/gcc/testsuite/gcc.dg/pr23470-1.c
new file mode 100644 (file)
index 0000000..2ddf6f2
--- /dev/null
@@ -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" } } */
index ce9daa6..6c8133f 100644 (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);