Commit e3232933 by Roger Sayle Committed by Roger Sayle

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

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
parent cf42869d
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).
......
......@@ -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)
......
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.
......
/* 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment