re PR middle-end/57073 (__builtin_powif (-1.0, k) should be optimized to "1.0 - 2...
authorTobias Burnus <burnus@gcc.gnu.org>
Thu, 30 May 2013 21:32:53 +0000 (23:32 +0200)
committerTobias Burnus <burnus@gcc.gnu.org>
Thu, 30 May 2013 21:32:53 +0000 (23:32 +0200)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/power_6.f90 [new file with mode: 0644]
gcc/tree-ssa-math-opts.c

index 660730a7b10c2d571c5c28fe660fed1844a29fa4..9086576410a08cabb8b95f3616da6e33a52be5d6 100644 (file)
@@ -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>
 
index 65443b9df4302ec144f8d71ba3ac1e3a2db26fbe..27bf13439d0351f1e81c1ed9c59a65db8fca4dbc 100644 (file)
@@ -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 (file)
index 0000000..65d1bd0
--- /dev/null
@@ -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" } }
index a94172d01cdf22365559657c82bc69da6a5bd1d4..a15c404286790c355e041bf7f47f7eee44da6ed3 100644 (file)
@@ -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)
                    {