mirror of
https://gcc.gnu.org/git/gcc.git
synced 2025-01-26 22:34:27 +08:00
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:
parent
cf42869d28
commit
e32329336b
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
33
gcc/testsuite/gcc.dg/20030826-1.c
Normal file
33
gcc/testsuite/gcc.dg/20030826-1.c
Normal 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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user