fold-const.c (tree_expr_nonnegative_p): Only return true for ABS_EXPR when flag_wrapv...
authorJames A. Morrison <phython@gcc.gnu.org>
Wed, 20 Jul 2005 03:30:58 +0000 (03:30 +0000)
committerJames A. Morrison <phython@gcc.gnu.org>
Wed, 20 Jul 2005 03:30:58 +0000 (03:30 +0000)
2005-07-19  James A. Morrison  <phython@gcc.gnu.org>

        * fold-const.c (tree_expr_nonnegative_p): Only return true for
        ABS_EXPR when flag_wrapv is false because of INT_MIN.
        (tree_expr_nonzero_p): Always call tree_expr_nonzero_p on the argument
        of an ABS_EXPR.
        (fold_unary): Always fold ABS_EXPR<ABS_EXPR<x>> into
        ABS_EXPR<x>.

From-SVN: r102184

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/fold-abs-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/fold-abs-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/fold-abs-3.c [new file with mode: 0644]

index 88073eb9e1a685860760e3e9a404babb21d3df6e..f37b254fcae2ed218859a8b100dc9ff07659a8df 100644 (file)
@@ -1,3 +1,12 @@
+2005-07-19  James A. Morrison  <phython@gcc.gnu.org>
+
+       * fold-const.c (tree_expr_nonnegative_p): Only return true for
+       ABS_EXPR when flag_wrapv is false because of INT_MIN.
+       (tree_expr_nonzero_p): Always call tree_expr_nonzero_p on the argument
+       of an ABS_EXPR.
+       (fold_unary): Always fold ABS_EXPR<ABS_EXPR<x>> into
+       ABS_EXPR<x>.
+
 2005-07-20  Giovanni Bajo  <giovannibajo@libero.it>
 
        Make CONSTRUCTOR use VEC to store initializers.
index 273a912d4e4ccb621d619e95c06d4639b3b84f1a..e9d88d1e6c3441b6928e71014f6cc4b5dc6b9669 100644 (file)
@@ -6827,7 +6827,8 @@ fold_unary (enum tree_code code, tree type, tree op0)
                                                    TREE_TYPE (targ0),
                                                    targ0));
        }
-      else if (tree_expr_nonnegative_p (arg0))
+      /* ABS_EXPR<ABS_EXPR<x>> = ABS_EXPR<x> even if flag_wrapv is on.  */
+      else if (tree_expr_nonnegative_p (arg0) || TREE_CODE (arg0) == ABS_EXPR)
        return arg0;
 
       /* Strip sign ops from argument.  */
@@ -10527,7 +10528,11 @@ tree_expr_nonnegative_p (tree t)
   switch (TREE_CODE (t))
     {
     case ABS_EXPR:
-      return 1;
+      /* We can't return 1 if flag_wrapv is set because
+        ABS_EXPR<INT_MIN> = INT_MIN.  */
+      if (!flag_wrapv)
+        return 1;
+      break;
 
     case INTEGER_CST:
       return tree_int_cst_sgn (t) >= 0;
@@ -10804,8 +10809,7 @@ tree_expr_nonzero_p (tree t)
   switch (TREE_CODE (t))
     {
     case ABS_EXPR:
-      if (!TYPE_UNSIGNED (type) && !flag_wrapv)
-       return tree_expr_nonzero_p (TREE_OPERAND (t, 0));
+      return tree_expr_nonzero_p (TREE_OPERAND (t, 0));
 
     case INTEGER_CST:
       /* We used to test for !integer_zerop here.  This does not work correctly
index 5d69c6faca40801d466b3572f6f98bf3d1fd4b0c..043d5128019632fbdc8567d37342a583bc7975b4 100644 (file)
@@ -1,3 +1,9 @@
+2005-07-19  James A. Morrison  <phython@gcc.gnu.org>
+
+       * gcc.dg/fold-abs-1.c: New test.
+       * gcc.dg/fold-abs-2.c: New test.
+       * gcc.dg/fold-abs-3.c: New test.
+
 2005-07-20  Giovanni Bajo  <giovannibajo@libero.it>
 
        Make CONSTRUCTOR use VEC to store initializers.
diff --git a/gcc/testsuite/gcc.dg/fold-abs-1.c b/gcc/testsuite/gcc.dg/fold-abs-1.c
new file mode 100644 (file)
index 0000000..2e69a20
--- /dev/null
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fwrapv" } */
+#define ABS(x) (x > 0 ? x : -x)
+int f (int a, int b) {
+       if ((ABS(a) | b) != 0) return 1;
+       else return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/fold-abs-2.c b/gcc/testsuite/gcc.dg/fold-abs-2.c
new file mode 100644 (file)
index 0000000..6291d7e
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-options "-O1 -fwrapv" } */
+#include <limits.h>
+void exit (int);
+void abort ();
+#define ABS(x) (x > 0 ? x : -x)
+int f (int a) {
+       if (ABS(a) >= 0) return 1;
+       else return 0;
+}
+
+int main (int argc, char *argv[]) {
+       if (f(INT_MIN))
+         abort ();
+       else
+         exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/fold-abs-3.c b/gcc/testsuite/gcc.dg/fold-abs-3.c
new file mode 100644 (file)
index 0000000..d151a8d
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-gimple -fwrapv" } */
+#define ABS(x) (x > 0 ? x : -x)
+int f (int a) {
+       return ABS (ABS(a));
+}
+
+/* { dg-final { scan-tree-dump-times "ABS" 1 "gimple" } } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */