From d24ad7d6e9397bc1514fe39e9855b0ac6a5489a2 Mon Sep 17 00:00:00 2001 From: Bill Schmidt Date: Wed, 25 May 2011 13:35:53 +0000 Subject: [PATCH] re PR tree-optimization/46728 (GCC does not generate fmadd for pow (x, 0.75)+y on powerpc) 2011-05-25 Bill Schmidt PR tree-optimization/46728 * tree-ssa-math-opts.c (gimple_expand_builtin_pow): New. (execute_cse_sincos): Add switch case for BUILT_IN_POW. From-SVN: r174196 --- gcc/ChangeLog | 12 ++++++++++ gcc/tree-ssa-math-opts.c | 52 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8811e14b5a4..1fc7adb540f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-05-25 Bill Schmidt + + PR tree-optimization/46728 + * tree-ssa-math-opts.c (gimple_expand_builtin_pow): New. + (execute_cse_sincos): Add switch case for BUILT_IN_POW. + 2011-05-25 Nathan Froyd * tree.h (struct tree_exp): Inherit from struct tree_typed. @@ -150,6 +156,12 @@ 2011-05-24 Bill Schmidt + PR tree-optimization/46728 + * tree-ssa-math-opts.c (gimple_expand_builtin_pow): New. + (execute_cse_sincos): Add switch case for BUILT_IN_POW. + +2011-05-24 Bill Schmidt + PR tree-optimization/46728 * tree-ssa-math-opts.c (powi_table): New. (powi_lookup_cost): New. diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index 26cdc693506..cd601e3dd0c 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -1,5 +1,5 @@ /* Global, SSA-based optimizations using mathematical identities. - Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 + Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -1024,6 +1024,39 @@ gimple_expand_builtin_powi (gimple_stmt_iterator *gsi, location_t loc, return NULL_TREE; } +/* ARG0 and ARG1 are the two arguments to a pow builtin call in GSI + with location info LOC. If possible, create an equivalent and + less expensive sequence of statements prior to GSI, and return an + expession holding the result. */ + +static tree +gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc, + tree arg0, tree arg1) +{ + REAL_VALUE_TYPE c, cint; + HOST_WIDE_INT n; + + /* If the exponent isn't a constant, there's nothing of interest + to be done. */ + if (TREE_CODE (arg1) != REAL_CST) + return NULL_TREE; + + /* If the exponent is equivalent to an integer, expand it into + multiplies when profitable. */ + c = TREE_REAL_CST (arg1); + n = real_to_integer (&c); + real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0); + + if (real_identical (&c, &cint) + && ((n >= -1 && n <= 2) + || (flag_unsafe_math_optimizations + && optimize_insn_for_speed_p () + && powi_cost (n) <= POWI_MAX_MULTS))) + return gimple_expand_builtin_powi (gsi, loc, arg0, n); + + return NULL_TREE; +} + /* Go through all calls to sin, cos and cexpi and call execute_cse_sincos_1 on the SSA_NAME argument of each of them. Also expand powi(x,n) into an optimal number of multiplies, when n is a constant. */ @@ -1065,6 +1098,23 @@ execute_cse_sincos (void) cfg_changed |= execute_cse_sincos_1 (arg); break; + CASE_FLT_FN (BUILT_IN_POW): + arg0 = gimple_call_arg (stmt, 0); + arg1 = gimple_call_arg (stmt, 1); + + loc = gimple_location (stmt); + result = gimple_expand_builtin_pow (&gsi, loc, arg0, arg1); + + if (result) + { + tree lhs = gimple_get_lhs (stmt); + gimple new_stmt = gimple_build_assign (lhs, result); + gimple_set_location (new_stmt, loc); + unlink_stmt_vdef (stmt); + gsi_replace (&gsi, new_stmt, true); + } + break; + CASE_FLT_FN (BUILT_IN_POWI): arg0 = gimple_call_arg (stmt, 0); arg1 = gimple_call_arg (stmt, 1); -- 2.30.2