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> 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 * builtins.c (fold_builtin_bitop): New function to perform constant
folding of ffs, clz, ctz, popcount and parity builtin functions folding of ffs, clz, ctz, popcount and parity builtin functions
and their long and long long variants (such as ffsl and ffsll). and their long and long long variants (such as ffsl and ffsll).
......
...@@ -6060,6 +6060,19 @@ fold (tree expr) ...@@ -6060,6 +6060,19 @@ fold (tree expr)
&& real_minus_onep (arg1)) && real_minus_onep (arg1))
return fold (build1 (NEGATE_EXPR, type, arg0)); 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) if (flag_unsafe_math_optimizations)
{ {
enum built_in_function fcode0 = builtin_mathfn_code (arg0); enum built_in_function fcode0 = builtin_mathfn_code (arg0);
...@@ -6393,7 +6406,7 @@ fold (tree expr) ...@@ -6393,7 +6406,7 @@ fold (tree expr)
arg1, 0))) arg1, 0)))
return fold (build (MULT_EXPR, type, arg0, tem)); return fold (build (MULT_EXPR, type, arg0, tem));
/* Find the reciprocal if optimizing and the result is exact. */ /* Find the reciprocal if optimizing and the result is exact. */
else if (optimize) if (optimize)
{ {
REAL_VALUE_TYPE r; REAL_VALUE_TYPE r;
r = TREE_REAL_CST (arg1); r = TREE_REAL_CST (arg1);
...@@ -6407,19 +6420,29 @@ fold (tree expr) ...@@ -6407,19 +6420,29 @@ fold (tree expr)
/* Convert A/B/C to A/(B*C). */ /* Convert A/B/C to A/(B*C). */
if (flag_unsafe_math_optimizations if (flag_unsafe_math_optimizations
&& TREE_CODE (arg0) == RDIV_EXPR) && TREE_CODE (arg0) == RDIV_EXPR)
{ return fold (build (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
return fold (build (RDIV_EXPR, type, TREE_OPERAND (arg0, 0), fold (build (MULT_EXPR, type,
build (MULT_EXPR, type, TREE_OPERAND (arg0, 1), TREE_OPERAND (arg0, 1), arg1))));
arg1)));
}
/* Convert A/(B/C) to (A/B)*C. */ /* Convert A/(B/C) to (A/B)*C. */
if (flag_unsafe_math_optimizations if (flag_unsafe_math_optimizations
&& TREE_CODE (arg1) == RDIV_EXPR) && 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, tree tem = const_binop (RDIV_EXPR, arg0,
build (RDIV_EXPR, type, arg0, TREE_OPERAND (arg1, 1), 0);
TREE_OPERAND (arg1, 0)), if (tem)
TREE_OPERAND (arg1, 1))); return fold (build (RDIV_EXPR, type, tem,
TREE_OPERAND (arg1, 0)));
} }
if (flag_unsafe_math_optimizations) 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> 2003-08-26 Matt Kraai <kraai@alumni.cmu.edu>
* gcc.dg/noncompile/20030818-1.c: Expect second line of error. * 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