diff options
author | Tobias Burnus <burnus@gcc.gnu.org> | 2013-05-30 23:32:53 +0200 |
---|---|---|
committer | Tobias Burnus <burnus@gcc.gnu.org> | 2013-05-30 23:32:53 +0200 |
commit | 0fa6e0eff715294ffe4c681e3779ff4aeb45eec9 (patch) | |
tree | 0338f41a27df644e6cb3e528642a32455d55caf9 /gcc/tree-ssa-math-opts.c | |
parent | 4688ddf59b247da24a4d5ebc22fb2c875b3c26cf (diff) | |
download | gcc-0fa6e0eff715294ffe4c681e3779ff4aeb45eec9.zip gcc-0fa6e0eff715294ffe4c681e3779ff4aeb45eec9.tar.gz gcc-0fa6e0eff715294ffe4c681e3779ff4aeb45eec9.tar.bz2 |
re PR middle-end/57073 (__builtin_powif (-1.0, k) should be optimized to "1.0 - 2.0 * (K%2)")
2013-05-30 Tobias Burnus <burnus@net-b.de>
Thomas Koenig <tkoenig@gcc.gnu.org>
PR middle-end/57073
* tree-ssa-math-opts.c (execute_cse_sincos): Optimize
powi (-1.0, k) to (k & 1) ? -1.0 : 1.0.
2013-05-30 Tobias Burnus <burnus@net-b.de>
PR middle-end/57073
* gfortran.dg/power_6.f90: New.
From-SVN: r199461
Diffstat (limited to 'gcc/tree-ssa-math-opts.c')
-rw-r--r-- | gcc/tree-ssa-math-opts.c | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index a94172d..a15c404 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -1445,12 +1445,43 @@ execute_cse_sincos (void) CASE_FLT_FN (BUILT_IN_POWI): arg0 = gimple_call_arg (stmt, 0); arg1 = gimple_call_arg (stmt, 1); - if (!host_integerp (arg1, 0)) - break; - - n = TREE_INT_CST_LOW (arg1); loc = gimple_location (stmt); - result = gimple_expand_builtin_powi (&gsi, loc, arg0, n); + + if (real_minus_onep (arg0) + && TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE + && !host_integerp (arg1,0)) + { + tree t0, t1, cond, one, minus_one; + gimple stmt; + + t0 = TREE_TYPE (arg0); + t1 = TREE_TYPE (arg1); + one = build_real (t0, dconst1); + minus_one = build_real (t0, dconstm1); + + cond = make_temp_ssa_name (t1, NULL, "powi_cond"); + stmt = gimple_build_assign_with_ops (BIT_AND_EXPR, cond, + arg1, + build_int_cst (t1, + 1)); + gimple_set_location (stmt, loc); + gsi_insert_before (&gsi, stmt, GSI_SAME_STMT); + + result = make_temp_ssa_name (t0, NULL, "powi"); + stmt = gimple_build_assign_with_ops (COND_EXPR, result, + cond, + minus_one, one); + gimple_set_location (stmt, loc); + gsi_insert_before (&gsi, stmt, GSI_SAME_STMT); + } + else + { + if (!host_integerp (arg1, 0)) + break; + + n = TREE_INT_CST_LOW (arg1); + result = gimple_expand_builtin_powi (&gsi, loc, arg0, n); + } if (result) { |