backport: re PR tree-optimization/56125 (-O2 -ffast-math generates bad code when dividing a double by the square of another double.)

Backported from mainline
	2013-01-28  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/56125
	* tree-ssa-math-opts.c (gimple_expand_builtin_pow): Don't optimize
	pow(x,c) into sqrt(x) * powi(x, n/2) or
	1.0 / (sqrt(x) * powi(x, abs(n/2))) if c is an integer or when
	optimizing for size.
	Don't optimize pow(x,c) into powi(x, n/3) * powi(cbrt(x), n%3) or
	1.0 / (powi(x, abs(n)/3) * powi(cbrt(x), abs(n)%3)) if 2c is an
	integer.

	* gcc.dg/pr56125.c: New test.

From-SVN: r195664
This commit is contained in:
Jakub Jelinek 2013-02-01 15:17:50 +01:00 committed by Jakub Jelinek
parent 2a1268b573
commit cba7a6d7ca
4 changed files with 47 additions and 4 deletions

View File

@ -1,6 +1,17 @@
2013-02-01 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2013-01-28 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/56125
* tree-ssa-math-opts.c (gimple_expand_builtin_pow): Don't optimize
pow(x,c) into sqrt(x) * powi(x, n/2) or
1.0 / (sqrt(x) * powi(x, abs(n/2))) if c is an integer or when
optimizing for size.
Don't optimize pow(x,c) into powi(x, n/3) * powi(cbrt(x), n%3) or
1.0 / (powi(x, abs(n)/3) * powi(cbrt(x), abs(n)%3)) if 2c is an
integer.
2013-01-25 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/56098

View File

@ -1,6 +1,11 @@
2013-02-01 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2013-01-28 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/56125
* gcc.dg/pr56125.c: New test.
2013-01-25 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/56098

View File

@ -0,0 +1,21 @@
/* PR tree-optimization/56125 */
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math" } */
extern void abort (void);
extern double fabs (double);
__attribute__((cold)) double
foo (double x, double n)
{
double u = x / (n * n);
return u;
}
int
main ()
{
if (fabs (foo (29, 2) - 7.25) > 0.001)
abort ();
return 0;
}

View File

@ -1113,7 +1113,7 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
tree type, sqrtfn, cbrtfn, sqrt_arg0, sqrt_sqrt, result, cbrt_x, powi_cbrt_x;
tree target = NULL_TREE;
enum machine_mode mode;
bool hw_sqrt_exists;
bool hw_sqrt_exists, c_is_int, c2_is_int;
/* If the exponent isn't a constant, there's nothing of interest
to be done. */
@ -1125,8 +1125,9 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
c = TREE_REAL_CST (arg1);
n = real_to_integer (&c);
real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
c_is_int = real_identical (&c, &cint);
if (real_identical (&c, &cint)
if (c_is_int
&& ((n >= -1 && n <= 2)
|| (flag_unsafe_math_optimizations
&& optimize_insn_for_speed_p ()
@ -1224,7 +1225,8 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
return build_and_insert_call (gsi, loc, &target, cbrtfn, sqrt_arg0);
}
/* Optimize pow(x,c), where n = 2c for some nonzero integer n, into
/* Optimize pow(x,c), where n = 2c for some nonzero integer n
and c not an integer, into
sqrt(x) * powi(x, n/2), n > 0;
1.0 / (sqrt(x) * powi(x, abs(n/2))), n < 0.
@ -1233,10 +1235,13 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
n = real_to_integer (&c2);
real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
c2_is_int = real_identical (&c2, &cint);
if (flag_unsafe_math_optimizations
&& sqrtfn
&& real_identical (&c2, &cint))
&& c2_is_int
&& !c_is_int
&& optimize_function_for_speed_p (cfun))
{
tree powi_x_ndiv2 = NULL_TREE;
@ -1289,6 +1294,7 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
&& cbrtfn
&& (gimple_val_nonnegative_real_p (arg0) || !HONOR_NANS (mode))
&& real_identical (&c2, &c)
&& !c2_is_int
&& optimize_function_for_speed_p (cfun)
&& powi_cost (n / 3) <= POWI_MAX_MULTS)
{