diff options
author | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-08-26 13:26:31 +0000 |
---|---|---|
committer | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-08-26 13:26:31 +0000 |
commit | f45a882cd66fe47eb20bebb90419fa0ed8819e74 (patch) | |
tree | 79ebdecf429956376ddd06509d488422d9478694 /gcc | |
parent | 70fb4c079170fe4c00d0d6b7747c9a2ce822f9d1 (diff) | |
download | gcc-f45a882cd66fe47eb20bebb90419fa0ed8819e74.tar.gz |
* fold-const.c (fold <MULT_EXPR>): Optimize (C1/X)*C2 into
(C1*C2)/X when unsafe math optimizations are allowed.
(fold <RDIV_EXPR>): 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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/fold-const.c | 43 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/20030826-1.c | 33 |
4 files changed, 78 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6c195ba1f4e..1b7d9708fa6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2003-08-26 Roger Sayle <roger@eyesopen.com> + * fold-const.c (fold <MULT_EXPR>): Optimize (C1/X)*C2 into + (C1*C2)/X when unsafe math optimizations are allowed. + (fold <RDIV_EXPR>): 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 <roger@eyesopen.com> + * 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 27a4724cabe..efa2db96637 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 1543516bedf..ba803a16550 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2003-08-26 Roger Sayle <roger@eyesopen.com> + + * gcc.dg/20030826-1.c: New test case. + 2003-08-26 Matt Kraai <kraai@alumni.cmu.edu> * 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 00000000000..b344ad2dcbc --- /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; +} + |