aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Kennedy <jimbob@google.com>2007-01-10 21:07:38 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2007-01-10 21:07:38 +0000
commit6b074ef6a052a19061eba1d2305c74277429d9bd (patch)
treebc31606a9a7b434c624657d340d54a055fe20619
parentee3202e1498c32d3119bcfd52af318585fb3dd72 (diff)
downloadgcc-6b074ef6a052a19061eba1d2305c74277429d9bd.zip
gcc-6b074ef6a052a19061eba1d2305c74277429d9bd.tar.gz
gcc-6b074ef6a052a19061eba1d2305c74277429d9bd.tar.bz2
fold-const.c (fold_comparison): Fold comparisons like (x * 1000 < 0) to (x < 0).
./: * fold-const.c (fold_comparison): Fold comparisons like (x * 1000 < 0) to (x < 0). testsuite/: * gcc.dg/fold-compare-2.c: New test case for fold_comparison. From-SVN: r120649
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/fold-const.c25
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/fold-compare-2.c18
4 files changed, 52 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6a52814..7b37633 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2007-01-10 Robert Kennedy <jimbob@google.com>
+
+ * fold-const.c (fold_comparison): Fold comparisons like (x *
+ 1000 < 0) to (x < 0).
+
2007-01-10 Ian Lance Taylor <iant@google.com>
* tree-pretty-print.c (dump_generic_node): Print parentheses when
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 3a3c1f9..9f116b5 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -8189,6 +8189,31 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
variable2);
}
+ /* Transform comparisons of the form X * C1 CMP 0 to X CMP 0 in the
+ signed arithmetic case. That form is created by the compiler
+ often enough for folding it to be of value. One example is in
+ computing loop trip counts after Operator Strength Reduction. */
+ if (!(flag_wrapv || flag_trapv)
+ && !TYPE_UNSIGNED (TREE_TYPE (arg0))
+ && TREE_CODE (arg0) == MULT_EXPR
+ && (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
+ && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1)))
+ && integer_zerop (arg1))
+ {
+ tree const1 = TREE_OPERAND (arg0, 1);
+ tree const2 = arg1; /* zero */
+ tree variable1 = TREE_OPERAND (arg0, 0);
+ enum tree_code cmp_code = code;
+
+ gcc_assert (!integer_zerop (const1));
+
+ /* If const1 is negative we swap the sense of the comparison. */
+ if (tree_int_cst_sgn (const1) < 0)
+ cmp_code = swap_tree_comparison (cmp_code);
+
+ return fold_build2 (cmp_code, type, variable1, const2);
+ }
+
tem = maybe_canonicalize_comparison (code, type, arg0, arg1);
if (tem)
return tem;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 71488e5..04dd13a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2007-01-10 Robert Kennedy <jimbob@google.com>
+
+ * gcc.dg/fold-compare-2.c: New test case for fold_comparison.
+
2007-01-09 Brooks Moses <brooks.moses@codesourcery.com>
* gfortran.dg/chkbits.f90: Added IBCLR tests; test calls
diff --git a/gcc/testsuite/gcc.dg/fold-compare-2.c b/gcc/testsuite/gcc.dg/fold-compare-2.c
new file mode 100644
index 0000000..79bade7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-compare-2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp" } */
+
+extern void abort (void);
+
+int a;
+
+int
+main(void)
+{
+ if (a * 1000 < 0)
+ abort ();
+ if (a * -43 > 0)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "Removing basic block" 1 "vrp1" } } */