diff options
author | Soumya AR <soumyaa@nvidia.com> | 2024-11-12 09:26:24 +0530 |
---|---|---|
committer | Soumya AR <soumyaa@nvidia.com> | 2024-11-12 09:30:33 +0530 |
commit | e232dc3bb5c3e8f8a3749239135b7b859a204fc7 (patch) | |
tree | ecc252b98a270feeb90b1f19aee01497e1c39789 | |
parent | 4b9bb1d687e77469b5926e89db3a34b32ed3194a (diff) | |
download | gcc-e232dc3bb5c3e8f8a3749239135b7b859a204fc7.zip gcc-e232dc3bb5c3e8f8a3749239135b7b859a204fc7.tar.gz gcc-e232dc3bb5c3e8f8a3749239135b7b859a204fc7.tar.bz2 |
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 <soumyaa@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.
-rw-r--r-- | gcc/match.pd | 15 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/log_exp.c | 40 |
2 files changed, 54 insertions, 1 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index 0098824..fc33b9a 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 0000000..1c5d967 --- /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; +} |