From f4185d2ba140576f0b8caa16dc495d8c4e122fc7 Mon Sep 17 00:00:00 2001 From: sayle Date: Fri, 7 Jun 2002 23:42:53 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@54356 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++ gcc/fold-const.c | 39 +++++++++++++++------ gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/20020607-2.c | 74 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/20020607-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index db56e7f45fe..afff77b7841 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2002-06-07 Roger Sayle + + * 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 * config.gcc (mips*-*-netbsd*): Add mips/t-netbsd to ${tmake_file}. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 6febe585d55..db415649f0f 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 576ef546f1f..ea104cf5335 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2002-06-07 Roger Sayle + + * gcc.dg/20020607-2.c: New test case. + 2002-06-07 Jakub Jelinek * 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 00000000000..239aa9b3880 --- /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; +} + -- 2.11.4.GIT