https://gcc.gnu.org/g:e232dc3bb5c3e8f8a3749239135b7b859a204fc7
commit r15-5116-ge232dc3bb5c3e8f8a3749239135b7b859a204fc7 Author: Soumya AR <soum...@nvidia.com> Date: Tue Nov 12 09:26:24 2024 +0530 Match: Optimize log (x) CMP CST and exp (x) CMP CST operations This patch implements transformations for the following optimizations. logN(x) CMP CST -> x CMP expN(CST) expN(x) CMP CST -> x CMP logN(CST) Where CMP expands to ge and le operations. For example: int foo (float x) { return __builtin_logf (x) <= 0.0f; } can just be: int foo (float x) { return x <= 1.0f; } The patch was bootstrapped and regtested on aarch64-linux-gnu, no regression. OK for mainline? Signed-off-by: Soumya AR <soum...@nvidia.com> gcc/ChangeLog: * match.pd: Fold logN(x) CMP CST -> x CMP expN(CST) and expN(x) CMP CST -> x CMP logN(CST) gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/log_exp.c: New test. Diff: --- gcc/match.pd | 15 ++++++++++++- gcc/testsuite/gcc.dg/tree-ssa/log_exp.c | 40 +++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/gcc/match.pd b/gcc/match.pd index 00988241348a..fc33b9ac3b1b 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -8347,7 +8347,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Simplify logN(a)-logN(b) into logN(a/b). */ (simplify (minus (logs:s @0) (logs:s @1)) - (logs (rdiv @0 @1))))) + (logs (rdiv @0 @1)))) + + (for cmp (le ge) + (for logs (LOG LOG2 LOG10) + exps (EXP EXP2 EXP10) + /* Simplify logN (x) CMP CST into x CMP expN (CST) */ + (simplify + (cmp:c (logs:s @0) REAL_CST@1) + (cmp @0 (exps @1))) + + /* Simplify expN (x) CMP CST into x CMP logN (CST) */ + (simplify + (cmp:c (exps:s @0) REAL_CST@1) + (cmp @0 (logs @1)))))) (for logs (LOG LOG2 LOG10 LOG10) exps (EXP EXP2 EXP10 POW10) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/log_exp.c b/gcc/testsuite/gcc.dg/tree-ssa/log_exp.c new file mode 100644 index 000000000000..1c5d967cdf76 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/log_exp.c @@ -0,0 +1,40 @@ +/* { dg-do link } */ +/* { dg-options "-O2 -ffast-math" } */ +/* { dg-require-effective-target c99_runtime } */ + +#include <stdbool.h> + +extern void link_error(void); + +#define T(FUNC1, FUNC2, CMP, TYPE, C_TY, ID) \ +void test_##FUNC1##_##FUNC2##_##ID (TYPE x) \ +{ \ + TYPE a = 10.0##C_TY; \ + TYPE t1 = __builtin_##FUNC1(x); \ + bool b1 = t1 CMP a; \ + TYPE t2 = __builtin_##FUNC2(a); \ + bool b2 = x CMP t2; \ + if (b1 != b2) \ + link_error(); \ +} + +#define TEST(FUNC1, FUNC2, TYPE, C_TY) \ + T(FUNC1, FUNC2, <=, TYPE, C_TY, 1) \ + T(FUNC1, FUNC2, >=, TYPE, C_TY, 2) \ + +#define TEST_ALL(TYPE, C_TY, F_TY) \ + TEST(exp##F_TY, log##F_TY, TYPE, C_TY) \ + TEST(exp2##F_TY, log2##F_TY, TYPE, C_TY) \ + TEST(exp10##F_TY, log10##F_TY, TYPE, C_TY) \ + TEST(log##F_TY, exp##F_TY, TYPE, C_TY) \ + TEST(log2##F_TY, exp2##F_TY, TYPE, C_TY) \ + TEST(log10##F_TY, exp10##F_TY, TYPE, C_TY) + +TEST_ALL(double, , ) +TEST_ALL(float, f, f) +TEST_ALL(long double, L, l) + +int main (void) +{ + return 0; +}