aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorTobias Burnus <burnus@gcc.gnu.org>2013-05-30 23:32:53 +0200
committerTobias Burnus <burnus@gcc.gnu.org>2013-05-30 23:32:53 +0200
commit0fa6e0eff715294ffe4c681e3779ff4aeb45eec9 (patch)
tree0338f41a27df644e6cb3e528642a32455d55caf9 /gcc
parent4688ddf59b247da24a4d5ebc22fb2c875b3c26cf (diff)
downloadgcc-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')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/power_6.f9015
-rw-r--r--gcc/tree-ssa-math-opts.c41
4 files changed, 64 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 660730a..9086576 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,13 @@
+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 Steven Bosscher <steven@gcc.gnu.org>
- * rtlanal.c (tablejump_p): Expect table and label to be adjacent.
+ * rtlanal.c (tablejump_p): Expect table and label to be adjacent.
2013-05-30 Vladimir Makarov <vmakarov@redhat.com>
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 65443b9..27bf134 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-05-30 Tobias Burnus <burnus@net-b.de>
+
+ PR middle-end/57073
+ * gfortran.dg/power_6.f90: New.
+
2013-05-30 Ian Bolton <ian.bolton@arm.com>
* gcc.target/aarch64/insv_1.c: New test.
diff --git a/gcc/testsuite/gfortran.dg/power_6.f90 b/gcc/testsuite/gfortran.dg/power_6.f90
new file mode 100644
index 0000000..65d1bd0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/power_6.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! { dg-options "-O1 -fdump-tree-optimized" }
+!
+! PR middle-end/57073
+! See also PR 57073
+!
+real function f(k)
+ integer, value :: k
+ f = (-1.0)**k
+end
+
+! { dg-final { scan-tree-dump-not "__builtin_powif" "optimized" } }
+! { dg-final { scan-tree-dump "powi_cond_\[0-9\] = k_\[0-9\]\\(D\\) & 1;" "optimized" } }
+! { dg-final { scan-tree-dump "powi_\[0-9\] = powi_cond_\[0-9\] \\? -1.0e\\+0 : 1.0e\\+0;" "optimized" } }
+! { dg-final { cleanup-tree-dump "optimized" } }
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)
{