Hi everyone,

this patch reduces calls to logarithm functions by
merging log a + log b => log a*b and
log a - log b => log a/b
This is my first contribution, so have I forgot something?
I think a contributor agreement is not needed since it's
a 20-line patch, and I may not have time to contribute in the
future.

Thank you for your comments.

2018-08-05  Deswurstes  <deswurs...@users.noreply.github.com>

gcc/
        PR tree-optimization/86710
        * match.pd: Add logarithm addition optimization

gcc/testsuite/
        PR tree-optimization/86710
        * gcc.dg/pr86710.c: Add logarithm tests

Index: gcc/match.pd
===================================================================
--- gcc/match.pd        (revision 263305)
+++ gcc/match.pd        (working copy)
@@ -4015,6 +4015,18 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    (exps (logs @0))
    @0))

+(for logs (LOG LOG2 LOG10)
+ /* x * logN(a) + y * logN(b) -> x * y * logN(a * b). */
+ (simplify
+  (plus:c (mult:c @0 (logs:s @1)) (mult:c @2 (logs:s @3)))
+  (mult (mult @0 @2) (logs (mult @1 @3))))
+
+(for logs (LOG LOG2 LOG10)
+ /* x * logN(a) - y * logN(b) -> x * logN(a / b) / y. */
+ (simplify
+  (sub (mult:c @0 (logs:s @1)) (mult:c @2 (logs:s @3)))
+  (rdiv (mult @0 (logs (rdiv @1 @3))) @3))
+
  /* Optimize logN(func()) for various exponential functions.  We
     want to determine the value "x" and the power "exponent" in
     order to transform logN(x**exponent) into exponent*logN(x).  */
Index: gcc/testsuite/gcc.dg/pr86710.c
===================================================================
--- gcc/testsuite/gcc.dg/pr86710.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/pr86710.c      (working copy)
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast" } */
+/* { dg-final { scan-assembler-not "log(.*)log(.*)log" } } */
+
+double c;
+
+void f1 (double x, double s)
+{
+  c = 5 * __builtin_log(x) + __builtin_log(s) / 2;
+}
+
+void f2 (double x, double s)
+{
+  c = __builtin_log(x) * 3 - 7 * __builtin_log(s);
+}

Besides, if you think optimizing
/* logN(a) + logN(b) -> logN(a * b) */
would be enough, without the coefficients,
here's a simpler patch:

Index: gcc/match.pd
===================================================================
--- gcc/match.pd    (revision 263305)
+++ gcc/match.pd    (working copy)
@@ -4015,6 +4015,18 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    (exps (logs @0))
    @0))

+(for logs (LOG LOG2 LOG10)
+ /* logN(a) + logN(b) -> logN(a * b). */
+ (simplify
+  (plus:c (logs:s (@0)) (logs:s (@1)))
+  (logs (mult (@0) (@1))))
+
+(for logs (LOG LOG2 LOG10)
+ /* logN(a) - logN(b) -> logN(a / b). */
+ (simplify
+  (sub (logs:s (@0)) (logs:s (@1)))
+  (logs (rdiv (@0) (@1))))
+
  /* Optimize logN(func()) for various exponential functions.  We
     want to determine the value "x" and the power "exponent" in
     order to transform logN(x**exponent) into exponent*logN(x).  */
Index: gcc/testsuite/gcc.dg/pr86710.c
===================================================================
--- gcc/testsuite/gcc.dg/pr86710.c    (nonexistent)
+++ gcc/testsuite/gcc.dg/pr86710.c    (working copy)
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "log(.*)log(.*)log" } } */
+
+double c;
+
+void f1 (double x, double s)
+{
+  c = __builtin_log(x) + __builtin_log(s);
+}
+
+void f2 (double x, double s)
+{
+  c = __builtin_log(x) - __builtin_log(s);
+}

Reply via email to