public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Improve pow (C, x) -> exp (log (C) * x) optimization (PR middle-end/84309)
@ 2018-02-09 23:49 Jakub Jelinek
  2018-02-10  7:00 ` Richard Biener
  2018-02-10 12:29 ` Marek Polacek
  0 siblings, 2 replies; 10+ messages in thread
From: Jakub Jelinek @ 2018-02-09 23:49 UTC (permalink / raw)
  To: Richard Biener, Jeff Law, Wilco Dijkstra; +Cc: gcc-patches

Hi!

Apparently the new pow(C,x) -> exp(log(C)*x) if C > 0 optimization
breaks some package (Marek should know which), as it has 7ulp error.
Generally one should be prepared for some errors with -ffast-math.

Though, in this case, if the target has c99 runtime and C is
a positive 0x1pNN it seems much better to use exp2 over exp, for
C being 2 pow (2, x) is optimized into exp2 (x) and even for other
values log2(C) will still be some positive or negative integer, so
in many cases there won't be any rounding errors in the multiplication.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Perhaps we should do something similar if C is a power of 10 (use exp10
and log10).

2018-02-10  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/84309
	* match.pd (pow(C,x) -> exp(log(C)*x)): Optimize instead into
	exp2(log2(C)*x) if C is a power of 2 and c99 runtime is available.

	* gcc.dg/pr84309.c: New test.
 
--- gcc/match.pd.jj	2018-01-26 12:43:23.208922420 +0100
+++ gcc/match.pd	2018-02-09 18:48:26.412021408 +0100
@@ -3992,15 +3992,33 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    (logs (pows @0 @1))
    (mult @1 (logs @0))))
 
- /* pow(C,x) -> exp(log(C)*x) if C > 0.  */
+ /* pow(C,x) -> exp(log(C)*x) if C > 0,
+    or if C is a positive power of 2,
+    pow(C,x) -> exp2(log2(C)*x).  */
  (for pows (POW)
       exps (EXP)
       logs (LOG)
+      exp2s (EXP2)
+      log2s (LOG2)
   (simplify
    (pows REAL_CST@0 @1)
-    (if (real_compare (GT_EXPR, TREE_REAL_CST_PTR (@0), &dconst0)
-	 && real_isfinite (TREE_REAL_CST_PTR (@0)))
-     (exps (mult (logs @0) @1)))))
+   (if (real_compare (GT_EXPR, TREE_REAL_CST_PTR (@0), &dconst0)
+	&& real_isfinite (TREE_REAL_CST_PTR (@0)))
+    (with {
+       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (@0);
+       bool use_exp2 = false;
+       if (targetm.libc_has_function (function_c99_misc)
+	   && value->cl == rvc_normal)
+	 {
+	   REAL_VALUE_TYPE frac_rvt = *value;
+	   SET_REAL_EXP (&frac_rvt, 1);
+	   if (real_equal (&frac_rvt, &dconst1))
+	     use_exp2 = true;
+	 }
+     }
+     (if (use_exp2)
+       (exp2s (mult (log2s @0) @1))
+       (exps (mult (logs @0) @1)))))))
 
  (for sqrts (SQRT)
       cbrts (CBRT)
--- gcc/testsuite/gcc.dg/pr84309.c.jj	2018-02-09 18:54:52.254787678 +0100
+++ gcc/testsuite/gcc.dg/pr84309.c	2018-02-09 18:59:02.343636178 +0100
@@ -0,0 +1,14 @@
+/* PR middle-end/84309 */
+/* { dg-do run { target c99_runtime } } */
+/* { dg-options "-O2 -ffast-math" } */
+
+int
+main ()
+{
+  unsigned long a = 1024;
+  unsigned long b = 16 * 1024;
+  unsigned long c = __builtin_pow (2, (__builtin_log2 (a) + __builtin_log2 (b)) / 2);
+  if (c != 4096)
+    __builtin_abort ();
+  return 0;
+}

	Jakub

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2018-02-13  7:59 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-09 23:49 [PATCH] Improve pow (C, x) -> exp (log (C) * x) optimization (PR middle-end/84309) Jakub Jelinek
2018-02-10  7:00 ` Richard Biener
2018-02-10  9:49   ` Jakub Jelinek
2018-02-10 11:29     ` Richard Biener
2018-02-10 17:49       ` Jakub Jelinek
2018-02-10 16:04         ` Richard Biener
2018-02-12 21:47         ` [PATCH] Improve pow (C, x) -> exp (log (C) * x) optimization (PR middle-end/84309, take 2) Jakub Jelinek
2018-02-13  7:59           ` Richard Biener
     [not found]     ` <DB6PR0801MB20531E5198E7A00B03443EB783F10@DB6PR0801MB2053.eurprd08.prod.outlook.com>
2018-02-12 22:01       ` [PATCH] Improve pow (C, x) -> exp (log (C) * x) optimization (PR middle-end/84309) Joseph Myers
2018-02-10 12:29 ` Marek Polacek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).