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

Reply via email to