This is an archive of the discontinued LLVM Phabricator instance.

[libc][math] Universal exp function for cosh/sinh calculation.
ClosedPublic

Authored by orex on Jul 6 2022, 9:15 AM.

Details

Summary

Added a function and test, which can be used later for cosh/sinh
and possibly for expf/expm1f.

latest sinhf/coshf performance:

CORE_MATH_PERF_MODE=rdtsc ./perf.sh coshf
GNU libc version: 2.31
GNU libc release: stable
30.155
12.267
13.525

CORE_MATH_PERF_MODE=rdtsc ./perf.sh sinhf
GNU libc version: 2.31
GNU libc release: stable
13.390
38.197
13.507

Diff Detail

Event Timeline

orex created this revision.Jul 6 2022, 9:15 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptJul 6 2022, 9:15 AM
orex requested review of this revision.Jul 6 2022, 9:15 AM
lntue added inline comments.Jul 19 2022, 8:49 PM
libc/src/math/generic/expxf.h
33

Use hexadecimal float constant.

49

static inline since this is in a header file.

50–54

You might want to try to see if using fputil::nearest_integer can improve the throughput or not:

double ps = fputil::nearest_integer(fputil::multiply_add(LN2_INV, x, static_cast<double>(ADD_TO_POS)));
int64_t ps_shifted = static_cast<int64_t>(ps) + (1 << (EXP_bits_p - 1));
...
67–68

You might want to use a fix representation of 1.0/6.0, ... 1.0/720.0 with hexadecimal floating point literals to reduce an uncertainty due to compiler constant evaluation methods and rounding modes.

lntue added a comment.Jul 19 2022, 8:57 PM

Can you add add_header_library for this in src/math/generic/CMakeLists.txt and use it as dependency for sinhf and coshf?

lntue added inline comments.Jul 19 2022, 9:19 PM
libc/src/math/generic/expxf.h
46

Can you add the range restriction for x in here, since it does not work for the whole double precision range?

58

Since in both sinhf and coshf, you have: 0.5 * ep, maybe you can fuse that * 0.5 here by:

bs.set_unbiased_exponent(fputil::FPBits<double>::EXPONENT_BIAS - 1 + dg)

If so, don't forget to update the comment about the returned value of mult_exp.

orex updated this revision to Diff 448129.Jul 27 2022, 12:27 PM
orex marked 5 inline comments as done.

Small fixes.

libc/src/math/generic/expxf.h
58

But, for tanh, I think that will be a problem. I introduced more general implementation.

orex edited the summary of this revision. (Show Details)Jul 27 2022, 12:29 PM
orex edited the summary of this revision. (Show Details)
lntue accepted this revision.Jul 27 2022, 12:34 PM
lntue added inline comments.
libc/test/src/math/expxf_test.cpp
37

Does it work for all rounding modes?

This revision is now accepted and ready to land.Jul 27 2022, 12:34 PM
orex updated this revision to Diff 448136.Jul 27 2022, 12:53 PM
orex edited the summary of this revision. (Show Details)

Small fixes in test.

orex added inline comments.
libc/test/src/math/expxf_test.cpp
37

This is an universal function, therefore it can have some exception and ranges, which should be treated separately in each math function, which use that one. Paul (@zimmermann6) independently confirm, that derivative functions gives perfect result for all rounding modes. My tests form others reviews shows the same.

I put all rounding modes to avoid such question in the future.