This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Improve pow (C, x) -> exp (log (C) * x) optimization (PR middle-end/84309)


On February 10, 2018 12:37:38 AM GMT+01:00, Jakub Jelinek <jakub@redhat.com> wrote:
>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?

OK. I wonder whether there are vectorized variants in libmvec? 

Richard. 

>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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]