]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/31029 (Fold does not fold C - a == a)
authorRichard Guenther <rguenther@suse.de>
Tue, 31 Mar 2009 14:28:16 +0000 (14:28 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 31 Mar 2009 14:28:16 +0000 (14:28 +0000)
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.

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

From-SVN: r145345

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 0f81767d3793f06eef748e3a61e70a7460a854dc..e38995188c1bb7d74dec17b1c95d218aeacf8e6d 100644 (file)
@@ -1,3 +1,9 @@
+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.
index 4951600a2976b18f5561a00f6a805ee7b7259ade..ec0695414124b9569930c5d4088a7ffdcde39401 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 9b1aef31f30688cf21b966a75da571e6bbe5256b..19cf3d6691d1003fae5a8f857642574eaa11e168 100644 (file)
@@ -1,3 +1,9 @@
+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.
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" } } */