aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2009-03-31 14:28:16 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2009-03-31 14:28:16 +0000
commit6b12efe971ad59e925d119243e6b6fabfdc2ba05 (patch)
tree3375dd6b6a930ea767bbaf4394885cf7b47d7023 /gcc
parent108f6c2f4efe0141c859eeb52fae610b8806ffc8 (diff)
downloadgcc-6b12efe971ad59e925d119243e6b6fabfdc2ba05.zip
gcc-6b12efe971ad59e925d119243e6b6fabfdc2ba05.tar.gz
gcc-6b12efe971ad59e925d119243e6b6fabfdc2ba05.tar.bz2
re PR middle-end/31029 (Fold does not fold C - a == a)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/fold-const.c33
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/fold-compare-4.c23
-rw-r--r--gcc/testsuite/gcc.dg/fold-compare-5.c20
5 files changed, 77 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0f81767..e389951 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 4951600..ec06954 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9b1aef3..19cf3d6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..d4bb64a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-compare-4.c
@@ -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
index 0000000..9ec8c33
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-compare-5.c
@@ -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" } } */