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); +}