summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2003-08-26 13:26:31 +0000
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2003-08-26 13:26:31 +0000
commitf45a882cd66fe47eb20bebb90419fa0ed8819e74 (patch)
tree79ebdecf429956376ddd06509d488422d9478694 /gcc
parent70fb4c079170fe4c00d0d6b7747c9a2ce822f9d1 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/fold-const.c43
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/20030826-1.c33
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;
+}
+