fold-const.c (fold): Fold -(~A) to A + 1.
authorJames A. Morrison <phython@gcc.gnu.org>
Tue, 15 Feb 2005 21:58:21 +0000 (21:58 +0000)
committerJames A. Morrison <phython@gcc.gnu.org>
Tue, 15 Feb 2005 21:58:21 +0000 (21:58 +0000)
2005-02-15  James A. Morrison  <phython@gcc.gnu.org>

        * fold-const.c (fold): Fold -(~A) to A + 1.  Fold ~(-A) to A - 1.
        Fold ~(A - 1) and ~(A + -1) to -A.

From-SVN: r95074

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

index 42e602b36873a0655e23f41ae7a265a8417a958e..a3b955e363e81dc22214516d320b882fc7b08135 100644 (file)
@@ -1,3 +1,8 @@
+2005-02-15  James A. Morrison  <phython@gcc.gnu.org>
+
+       * fold-const.c (fold): Fold -(~A) to A + 1.  Fold ~(-A) to A - 1.
+       Fold ~(A - 1) and ~(A + -1) to -A.
+
 2005-02-15  James A. Morrison  <phython@gcc.gnu.org>
 
        PR pch/14940
index 03285ec523b17ecc6a245c047329f0fd4a7eec6f..ef31a32f54ef63a2f4630f92195659cffadb5c4a 100644 (file)
@@ -6931,6 +6931,10 @@ fold (tree expr)
     case NEGATE_EXPR:
       if (negate_expr_p (arg0))
        return fold_convert (type, negate_expr (arg0));
+      /* Convert - (~A) to A + 1.  */
+      if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == BIT_NOT_EXPR)
+       return fold (build2 (PLUS_EXPR, type, TREE_OPERAND (arg0, 0),
+                            build_int_cst (type, 1)));
       return t;
 
     case ABS_EXPR:
@@ -6985,6 +6989,17 @@ fold (tree expr)
         return fold_not_const (arg0, type);
       else if (TREE_CODE (arg0) == BIT_NOT_EXPR)
        return TREE_OPERAND (arg0, 0);
+      /* Convert ~ (-A) to A - 1.  */
+      else if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR)
+       return fold (build2 (MINUS_EXPR, type, TREE_OPERAND (arg0, 0),
+                            build_int_cst (type, 1)));
+      /* Convert ~ (A - 1) or ~ (A + -1) to -A.  */
+      else if (INTEGRAL_TYPE_P (type)
+              && ((TREE_CODE (arg0) == MINUS_EXPR
+                   && integer_onep (TREE_OPERAND (arg0, 1)))
+                  || (TREE_CODE (arg0) == PLUS_EXPR
+                      && integer_all_onesp (TREE_OPERAND (arg0, 1)))))
+       return fold (build1 (NEGATE_EXPR, type, TREE_OPERAND (arg0, 0)));
       return t;
 
     case PLUS_EXPR:
index 1a66c5eddfb71066c8dee21667f8b8ff18591c93..fc56108b49e55dbe0addd8ec3921cda90f22c984 100644 (file)
@@ -1,3 +1,8 @@
+2005-02-15  James A. Morrison  <phython@gcc.gnu.org>
+
+       PR tree-optimization/15785
+       * gcc.dg/pr15785-1.c: New test.
+
 2005-02-15  Alexandre Oliva  <aoliva@redhat.com>
 
        PR c++/17788
diff --git a/gcc/testsuite/gcc.dg/pr15785-1.c b/gcc/testsuite/gcc.dg/pr15785-1.c
new file mode 100644 (file)
index 0000000..47cd3d7
--- /dev/null
@@ -0,0 +1,42 @@
+/* { dg-do link } */
+
+extern void link_error ();
+
+void a (int x) {
+       if (~ (~x) - x)
+               link_error ();
+}
+void b (int x) {
+       if (- (-x) - x)
+               link_error ();
+}
+
+void c (int x) {
+       if (!(- (~x) - x))
+               link_error ();
+}
+
+void d (int x) {
+       if (!(~ (-x) - x))
+               link_error ();
+}
+
+void e (int x) {
+       if (x + ~(x - 1))
+               link_error ();
+}
+
+void f (int x) {
+       if (x + ~(x + (-1)))
+               link_error ();
+}
+
+int main (int argc, char *argv[]) {
+       a(argc);
+       b(argc);
+       c(argc);
+       d(argc);
+       e(argc);
+       f(argc);
+       return 0;
+}