From f45a882cd66fe47eb20bebb90419fa0ed8819e74 Mon Sep 17 00:00:00 2001 From: sayle Date: Tue, 26 Aug 2003 13:26:31 +0000 Subject: [PATCH] * fold-const.c (fold ): Optimize (C1/X)*C2 into (C1*C2)/X when unsafe math optimizations are allowed. (fold ): Optimize C1/(X*C2) into (C1/C2)/X with unsafe math optimizations. Minor code clean-ups. Recursively call fold when constructing sub-expressions. * gcc.dg/20030826-1.c: New test case. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@70807 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 ++++++++ gcc/fold-const.c | 43 ++++++++++++++++++++++++++++++--------- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.dg/20030826-1.c | 33 ++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/20030826-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6c195ba..1b7d970 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2003-08-26 Roger Sayle + * fold-const.c (fold ): Optimize (C1/X)*C2 into + (C1*C2)/X when unsafe math optimizations are allowed. + (fold ): Optimize C1/(X*C2) into (C1/C2)/X with unsafe + math optimizations. Minor code clean-ups. Recursively call + fold when constructing sub-expressions. + +2003-08-26 Roger Sayle + * builtins.c (fold_builtin_bitop): New function to perform constant folding of ffs, clz, ctz, popcount and parity builtin functions and their long and long long variants (such as ffsl and ffsll). diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 27a4724c..efa2db9 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -6060,6 +6060,19 @@ fold (tree expr) && real_minus_onep (arg1)) return fold (build1 (NEGATE_EXPR, type, arg0)); + /* Convert (C1/X)*C2 into (C1*C2)/X. */ + if (flag_unsafe_math_optimizations + && TREE_CODE (arg0) == RDIV_EXPR + && TREE_CODE (arg1) == REAL_CST + && TREE_CODE (TREE_OPERAND (arg0, 0)) == REAL_CST) + { + tree tem = const_binop (MULT_EXPR, TREE_OPERAND (arg0, 0), + arg1, 0); + if (tem) + return fold (build (RDIV_EXPR, type, tem, + TREE_OPERAND (arg0, 1))); + } + if (flag_unsafe_math_optimizations) { enum built_in_function fcode0 = builtin_mathfn_code (arg0); @@ -6393,7 +6406,7 @@ fold (tree expr) arg1, 0))) return fold (build (MULT_EXPR, type, arg0, tem)); /* Find the reciprocal if optimizing and the result is exact. */ - else if (optimize) + if (optimize) { REAL_VALUE_TYPE r; r = TREE_REAL_CST (arg1); @@ -6407,19 +6420,29 @@ fold (tree expr) /* Convert A/B/C to A/(B*C). */ if (flag_unsafe_math_optimizations && TREE_CODE (arg0) == RDIV_EXPR) - { - return fold (build (RDIV_EXPR, type, TREE_OPERAND (arg0, 0), - build (MULT_EXPR, type, TREE_OPERAND (arg0, 1), - arg1))); - } + return fold (build (RDIV_EXPR, type, TREE_OPERAND (arg0, 0), + fold (build (MULT_EXPR, type, + TREE_OPERAND (arg0, 1), arg1)))); + /* Convert A/(B/C) to (A/B)*C. */ if (flag_unsafe_math_optimizations && TREE_CODE (arg1) == RDIV_EXPR) + return fold (build (MULT_EXPR, type, + fold (build (RDIV_EXPR, type, arg0, + TREE_OPERAND (arg1, 0))), + TREE_OPERAND (arg1, 1))); + + /* Convert C1/(X*C2) into (C1/C2)/X. */ + if (flag_unsafe_math_optimizations + && TREE_CODE (arg1) == MULT_EXPR + && TREE_CODE (arg0) == REAL_CST + && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST) { - return fold (build (MULT_EXPR, type, - build (RDIV_EXPR, type, arg0, - TREE_OPERAND (arg1, 0)), - TREE_OPERAND (arg1, 1))); + tree tem = const_binop (RDIV_EXPR, arg0, + TREE_OPERAND (arg1, 1), 0); + if (tem) + return fold (build (RDIV_EXPR, type, tem, + TREE_OPERAND (arg1, 0))); } if (flag_unsafe_math_optimizations) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1543516..ba803a1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2003-08-26 Roger Sayle + + * gcc.dg/20030826-1.c: New test case. + 2003-08-26 Matt Kraai * gcc.dg/noncompile/20030818-1.c: Expect second line of error. diff --git a/gcc/testsuite/gcc.dg/20030826-1.c b/gcc/testsuite/gcc.dg/20030826-1.c new file mode 100644 index 0000000..b344ad2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20030826-1.c @@ -0,0 +1,33 @@ +/* Copyright (C) 2003 Free Software Foundation. + + Check that constant folding of mathematical expressions doesn't + break anything. + + Written by Roger Sayle, 24th August 2003. */ + +/* { dg-do run } */ +/* { dg-options "-O2 -ffast-math" } */ + +void abort(void); + +double foo(double x) +{ + return 12.0/(x*3.0); +} + +double bar(double x) +{ + return (3.0/x)*4.0; +} + +int main() +{ + if (foo(2.0) != 2.0) + abort (); + + if (bar(2.0) != 6.0) + abort (); + + return 0; +} + -- 2.7.4