aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2002-06-07 23:42:53 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2002-06-07 23:42:53 +0000
commit437f1df1afacb10132608f3cf27f4289c1bdbe1c (patch)
treebfcf15db0019b5665c4cb88b677704f02c0b89ad
parentcd24b8a4033454aaac4cf053291fbc9bd0743016 (diff)
downloadgcc-437f1df1afacb10132608f3cf27f4289c1bdbe1c.zip
gcc-437f1df1afacb10132608f3cf27f4289c1bdbe1c.tar.gz
gcc-437f1df1afacb10132608f3cf27f4289c1bdbe1c.tar.bz2
fold-const.c (fold): Place both integer and real constants last in comparisons.
* fold-const.c (fold) [EQ_EXPR]: Place both integer and real constants last in comparisons. Optimize (x+1.0)>0.0 into the equivalent x > -1.0 when -ffast-math. * gcc.dg/20020607-2.c: New test case. From-SVN: r54356
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/fold-const.c39
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/20020607-2.c74
4 files changed, 112 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index db56e7f..afff77b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2002-06-07 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold) [EQ_EXPR]: Place both integer and real
+ constants last in comparisons. Optimize (x+1.0)>0.0 into the
+ equivalent x > -1.0 when -ffast-math.
+
2002-06-07 Jason Thorpe <thorpej@wasabisystems.com>
* config.gcc (mips*-*-netbsd*): Add mips/t-netbsd to ${tmake_file}.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 6febe58..db41564 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -5814,6 +5814,20 @@ fold (expr)
case GT_EXPR:
case LE_EXPR:
case GE_EXPR:
+ /* If one arg is a real or integer constant, put it last. */
+ if ((TREE_CODE (arg0) == INTEGER_CST
+ && TREE_CODE (arg1) != INTEGER_CST)
+ || (TREE_CODE (arg0) == REAL_CST
+ && TREE_CODE (arg0) != REAL_CST))
+ {
+ TREE_OPERAND (t, 0) = arg1;
+ TREE_OPERAND (t, 1) = arg0;
+ arg0 = TREE_OPERAND (t, 0);
+ arg1 = TREE_OPERAND (t, 1);
+ code = swap_tree_comparison (code);
+ TREE_SET_CODE (t, code);
+ }
+
if (FLOAT_TYPE_P (TREE_TYPE (arg0)))
{
/* (-a) CMP (-b) -> b CMP a */
@@ -5835,18 +5849,21 @@ fold (expr)
&& REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (arg1)))
return fold (build (code, type, arg0,
build_real (TREE_TYPE (arg1), dconst0)));
- }
- /* If one arg is a constant integer, put it last. */
- if (TREE_CODE (arg0) == INTEGER_CST
- && TREE_CODE (arg1) != INTEGER_CST)
- {
- TREE_OPERAND (t, 0) = arg1;
- TREE_OPERAND (t, 1) = arg0;
- arg0 = TREE_OPERAND (t, 0);
- arg1 = TREE_OPERAND (t, 1);
- code = swap_tree_comparison (code);
- TREE_SET_CODE (t, code);
+ /* If this is a comparison of a real constant with a PLUS_EXPR
+ or a MINUS_EXPR of a real constant, we can convert it into a
+ comparison with a revised real constant as long as no overflow
+ occurs when unsafe_math_optimizations are enabled. */
+ if (flag_unsafe_math_optimizations
+ && TREE_CODE (arg1) == REAL_CST
+ && (TREE_CODE (arg0) == PLUS_EXPR
+ || TREE_CODE (arg0) == MINUS_EXPR)
+ && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
+ && 0 != (tem = const_binop (TREE_CODE (arg0) == PLUS_EXPR
+ ? MINUS_EXPR : PLUS_EXPR,
+ arg1, TREE_OPERAND (arg0, 1), 0))
+ && ! TREE_CONSTANT_OVERFLOW (tem))
+ return fold (build (code, type, TREE_OPERAND (arg0, 0), tem));
}
/* Convert foo++ == CONST into ++foo == CONST + INCR.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 576ef54..ea104cf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2002-06-07 Roger Sayle <roger@eyesopen.com>
+
+ * gcc.dg/20020607-2.c: New test case.
+
2002-06-07 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/compile/20020604-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/20020607-2.c b/gcc/testsuite/gcc.dg/20020607-2.c
new file mode 100644
index 0000000..239aa9b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20020607-2.c
@@ -0,0 +1,74 @@
+/* Copyright (C) 2002 Free Software Foundation.
+
+ Test for correctness of floating point comparisons.
+
+ Written by Roger Sayle, 3rd June 2002. */
+
+/* { dg-do run } */
+/* { dg-options "-O2 -ffast-math" } */
+
+extern void abort (void);
+
+int test1 (double x, int ok)
+{
+ if ((x - 1.0) > 0.0)
+ {
+ if (!ok) abort ();
+ }
+ else
+ if (ok) abort ();
+}
+
+int test1f (float x, int ok)
+{
+ if ((x - 1.0f) > 0.0f)
+ {
+ if (!ok) abort ();
+ }
+ else
+ if (ok) abort ();
+}
+
+int test2 (double x, int ok)
+{
+ if ((x + 1.0) < 0.0)
+ {
+ if (!ok) abort ();
+ }
+ else
+ if (ok) abort ();
+}
+
+int test2f (float x, int ok)
+{
+ if ((x + 1.0f) < 0.0f)
+ {
+ if (!ok) abort ();
+ }
+ else
+ if (ok) abort ();
+}
+
+
+int
+main ()
+{
+ test1 (-2.0, 0);
+ test1 ( 0.0, 0);
+ test1 ( 2.0, 1);
+
+ test1f (-2.0f, 0);
+ test1f ( 0.0f, 0);
+ test1f ( 2.0f, 1);
+
+ test2 (-2.0, 1);
+ test2 ( 0.0, 0);
+ test2 ( 2.0, 0);
+
+ test2f (-2.0f, 1);
+ test2f ( 0.0f, 0);
+ test2f ( 2.0f, 0);
+
+ return 0;
+}
+