fold-const.c (fold <MULT_EXPR>): Optimize (C1/X)*C2 into (C1*C2)/X when unsafe math optimizations are allowed.

* 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.

From-SVN: r70807
This commit is contained in:
Roger Sayle 2003-08-26 13:26:31 +00:00 committed by Roger Sayle
parent cf42869d28
commit e32329336b
4 changed files with 78 additions and 10 deletions

View File

@ -1,3 +1,11 @@
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

View File

@ -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)

View File

@ -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.

View File

@ -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;
}