aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames A. Morrison <phython@gcc.gnu.org>2005-02-15 21:58:21 +0000
committerJames A. Morrison <phython@gcc.gnu.org>2005-02-15 21:58:21 +0000
commitf73a89db0c07f04303b672d649faaa1f1336c2b8 (patch)
tree0738a0f6031b2fb475ab674da3644b67dcb22345
parent080d9fe92d0138df469f073b841e678e0948bbaa (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@95074 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/fold-const.c15
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr15785-1.c42
4 files changed, 67 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 42e602b3687..a3b955e363e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
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
PR target/19300
* config/host-linux.c (linux_gt_pch_use_address): Copy from
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 03285ec523b..ef31a32f54e 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1a66c5eddfb..fc56108b49e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..47cd3d7b01b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr15785-1.c
@@ -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;
+}