fold-const.c (fold): Transform (c1 - x) cmp c2...
authorRoger Sayle <roger@eyesopen.com>
Mon, 14 Apr 2003 20:16:58 +0000 (20:16 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Mon, 14 Apr 2003 20:16:58 +0000 (20:16 +0000)
* fold-const.c (fold):  Transform (c1 - x) cmp c2, where cmp is a
comparison operation and c1/c2 are floating point constants into
x swap(cmp) (c1 - c2).

* gcc.dg/20030414-2.c: New test case.

From-SVN: r65584

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

index 05b01f9..bf11841 100644 (file)
@@ -1,3 +1,9 @@
+2003-04-14  Roger Sayle  <roger@eyesopen.com>
+
+       * fold-const.c (fold):  Transform (c1 - x) cmp c2, where cmp is a
+       comparison operation and c1/c2 are floating point constants into
+       x swap(cmp) (c1 - c2).
+
 2003-04-14  Vladimir Makarov  <vmakarov@redhat.com>
 
        * genautomata.c (output_translate_vect): Fix a typo in loop
@@ -1376,7 +1382,7 @@ Thu Apr  3 00:18:49 CEST 2003  Jan Hubicka  <jh@suse.cz>
 2003-04-01  Roger Sayle  <roger@eyesopen.com>
 
        PR fortran/9974
-       * gcse.c (reg_killed_on_egde): New function to test whether the
+       * gcse.c (reg_killed_on_edge): New function to test whether the
        given reg is overwritten by any instruction queued on an edge.
        (bypass_block): Ignore substitutions killed on incoming edges.
        Don't bypass outgoing edges that have queued instructions.
index ebb87e2..95812a2 100644 (file)
@@ -6484,6 +6484,19 @@ fold (expr)
              && ! TREE_CONSTANT_OVERFLOW (tem))
            return fold (build (code, type, TREE_OPERAND (arg0, 0), tem));
 
+         /* Likewise, we can simplify a comparison of a real constant with
+            a MINUS_EXPR whose first operand is also a real constant, i.e.
+            (c1 - x) < c2 becomes x > c1-c2.  */
+         if (flag_unsafe_math_optimizations
+             && TREE_CODE (arg1) == REAL_CST
+             && TREE_CODE (arg0) == MINUS_EXPR
+             && TREE_CODE (TREE_OPERAND (arg0, 0)) == REAL_CST
+             && 0 != (tem = const_binop (MINUS_EXPR, TREE_OPERAND (arg0, 0),
+                                         arg1, 0))
+             && ! TREE_CONSTANT_OVERFLOW (tem))
+           return fold (build (swap_tree_comparison (code), type,
+                               TREE_OPERAND (arg0, 1), tem));
+
          /* Fold comparisons against built-in math functions.  */
          if (TREE_CODE (arg1) == REAL_CST
              && flag_unsafe_math_optimizations
index 214ed1a..1fc22ee 100644 (file)
@@ -1,3 +1,7 @@
+2003-04-14  Roger Sayle  <roger@eyesopen.com>
+
+       * gcc.dg/20030414-2.c: New test case.
+
 2003-04-14  Hans-Peter Nilsson  <hp@axis.com>
 
        PR target/10377
diff --git a/gcc/testsuite/gcc.dg/20030414-2.c b/gcc/testsuite/gcc.dg/20030414-2.c
new file mode 100644 (file)
index 0000000..f4eb8bf
--- /dev/null
@@ -0,0 +1,38 @@
+/* Copyright (C) 2003 Free Software Foundation.
+
+   Check that constant folding (c1 - x) op c2 into x swap(op) c1-c2
+   doesn't break anything.
+
+   Written by Roger Sayle, 27th March 2003.  */
+
+/* { dg-do run } */
+/* { dg-options "-O2 -ffast-math" } */
+
+extern void abort (void);
+
+int foo(double x)
+{
+  return (10.0 - x) > 3.0;
+}
+
+int bar (double x)
+{
+  return (10.0 - x) == 5.0;
+}
+
+int main()
+{
+  if (foo (8.0))
+    abort ();
+
+  if (! foo (6.0))
+    abort ();
+
+  if (bar (1.0))
+    abort ();
+
+  if (! bar (5.0))
+    abort ();
+  return 0;
+}
+