OSDN Git Service

2009-03-31 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 31 Mar 2009 14:28:16 +0000 (14:28 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 31 Mar 2009 14:28:16 +0000 (14:28 +0000)
PR middle-end/31029
* fold-const.c (fold_binary): Fold X +- Y CMP X to Y CMP 0 for
equality comparisons.  Fold C - X CMP X if C % 2 == 1.

* gcc.dg/fold-compare-4.c: New testcase.
* gcc.dg/fold-compare-5.c: Likewise.

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

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/fold-compare-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/fold-compare-5.c [new file with mode: 0644]

index 0f81767..e389951 100644 (file)
@@ -1,5 +1,11 @@
 2009-03-31  Richard Guenther  <rguenther@suse.de>
 
+       PR middle-end/31029
+       * fold-const.c (fold_binary): Fold X +- Y CMP X to Y CMP 0 for
+       equality comparisons.  Fold C - X CMP X if C % 2 == 1.
+
+2009-03-31  Richard Guenther  <rguenther@suse.de>
+
        * tree.h (div_if_zero_remainder): Declare.
        * fold-const.c (div_if_zero_remainder): Export.
        * tree-ssa-forwprop.c
index 4951600..ec06954 100644 (file)
@@ -12191,22 +12191,33 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
                                         fold_convert (TREE_TYPE (arg0), arg1),
                                         TREE_OPERAND (arg0, 1)));
 
-      /* Transform comparisons of the form X +- C CMP X.  */
-      if ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
+      /* Transform comparisons of the form X +- Y CMP X to Y CMP 0.  */
+      if ((TREE_CODE (arg0) == PLUS_EXPR
+          || TREE_CODE (arg0) == POINTER_PLUS_EXPR
+          || TREE_CODE (arg0) == MINUS_EXPR)
          && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
-         && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
          && (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
              || POINTER_TYPE_P (TREE_TYPE (arg0))))
        {
-         tree cst = TREE_OPERAND (arg0, 1);
+         tree val = TREE_OPERAND (arg0, 1);
+         return omit_two_operands (type,
+                                   fold_build2 (code, type,
+                                                val,
+                                                build_int_cst (TREE_TYPE (val),
+                                                               0)),
+                                   TREE_OPERAND (arg0, 0), arg1);
+       }
 
-         if (code == EQ_EXPR
-             && !integer_zerop (cst))
-           return omit_two_operands (type, boolean_false_node,
-                                     TREE_OPERAND (arg0, 0), arg1);
-         else
-           return omit_two_operands (type, boolean_true_node,
-                                     TREE_OPERAND (arg0, 0), arg1);
+      /* Transform comparisons of the form C - X CMP X if C % 2 == 1.  */
+      if (TREE_CODE (arg0) == MINUS_EXPR
+         && TREE_CODE (TREE_OPERAND (arg0, 0)) == INTEGER_CST
+         && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0)
+         && (TREE_INT_CST_LOW (TREE_OPERAND (arg0, 0)) & 1) == 1)
+       {
+         return omit_two_operands (type,
+                                   code == NE_EXPR
+                                   ? boolean_true_node : boolean_false_node,
+                                   TREE_OPERAND (arg0, 1), arg1);
        }
 
       /* If we have X - Y == 0, we can convert that to X == Y and similarly
index 9b1aef3..19cf3d6 100644 (file)
@@ -1,5 +1,11 @@
 2009-03-31  Richard Guenther  <rguenther@suse.de>
 
+       PR middle-end/31029
+       * gcc.dg/fold-compare-4.c: New testcase.
+       * gcc.dg/fold-compare-5.c: Likewise.
+
+2009-03-31  Richard Guenther  <rguenther@suse.de>
+
        * gcc.dg/tree-ssa/forwprop-12.c: New testcase.
 
 2009-03-31  Joseph Myers  <joseph@codesourcery.com>
diff --git a/gcc/testsuite/gcc.dg/fold-compare-4.c b/gcc/testsuite/gcc.dg/fold-compare-4.c
new file mode 100644 (file)
index 0000000..d4bb64a
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-original" } */
+
+int test1 (int a, int b)
+{
+  return a - b == a;
+}
+int test2 (int a, int b)
+{
+  return a + b == a;
+}
+int test3 (int a)
+{
+  return a + 5 == a;
+}
+int test4 (int a)
+{
+  return a - 5 == a;
+}
+
+/* { dg-final { scan-tree-dump-times "b == 0" 2 "original" } } */
+/* { dg-final { scan-tree-dump-times "return 0" 2 "original" } } */
+/* { dg-final { cleanup-tree-dump "original" } } */
diff --git a/gcc/testsuite/gcc.dg/fold-compare-5.c b/gcc/testsuite/gcc.dg/fold-compare-5.c
new file mode 100644 (file)
index 0000000..9ec8c33
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-original" } */
+
+int test1 (int a)
+{
+  return 2 - a == a;
+}
+int test2 (int a)
+{
+  return 1 - a == a;
+}
+int test3 (int a)
+{
+  return 1 - a != a;
+}
+
+/* { dg-final { scan-tree-dump-times "return 2 - a == a" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "return 0" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "return 1" 1 "original" } } */
+/* { dg-final { cleanup-tree-dump "original" } } */