OSDN Git Service

./:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 10 Jan 2007 21:07:38 +0000 (21:07 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 10 Jan 2007 21:07:38 +0000 (21:07 +0000)
* 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.

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

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

index 6a52814..7b37633 100644 (file)
@@ -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
index 3a3c1f9..9f116b5 100644 (file)
@@ -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;
index 71488e5..04dd13a 100644 (file)
@@ -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 (file)
index 0000000..79bade7
--- /dev/null
@@ -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" } } */