GCC should support inline code generation for sinh, cosh, tanh functions, under appropriate fast-math conditions. glibc's bits/mathinline.h, for 32-bit non-SSE fast-math x86 only, has: /* The argument range of the inline version of sinhl is slightly reduced. */ __inline_mathcodeNP (sinh, __x, \ register long double __exm1 = __expm1l (__fabsl (__x)); \ return 0.5 * (__exm1 / (__exm1 + 1.0) + __exm1) * __sgn1l (__x)) __inline_mathcodeNP (cosh, __x, \ register long double __ex = __expl (__x); \ return 0.5 * (__ex + 1.0 / __ex)) __inline_mathcodeNP (tanh, __x, \ register long double __exm1 = __expm1l (-__fabsl (__x + __x)); \ return __exm1 / (__exm1 + 2.0) * __sgn1l (-__x)) We're moving away from such inlines in glibc, preferring to leave it to the compiler to inline standard functions under appropriate conditions. This inlining probably only makes sense when expm1l / expl are themselves expanded inline (but in principle it's otherwise generic; note this x86 code uses long double, so avoiding reducing the argument range for built-in functions for narrower types). flag_unsafe_math_optimizations should be required for all these expansions; the sinh one is specifically unsafe for infinite arguments so should also require flag_finite_math_only.
glibc does this because its __expm1l implementation happens to be fast? That is, the question would be whether this falls under "canonicalization" and thus appropriate for a match.pd pattern? Of course if x87 has exmp1 then optab expansion of those functions would be appropriate as well. Though again this can be achieved via generic code querying for such support via direct_optab_supported_p. Does glibc have vectorized expm1 so that via this expansion we coudl vectorize a loop containing sinh() calls?
For any vaguely recent GCC version, the now-removed code in bits/mathinline.h used __builtin_expm1l. The key features for this (and much the same applies to the hypot / asinh / acosh / atanh inlines which have also been added as x86-specific) are: * optab to expand expm1l inline (using the x87 f2xm1 instruction, though it's more complicated than that), respectively to expand expl inline in one case (and other functions such as log1pl for the inverse hyperbolic functions). * Operations including that optab available for a wider type (XFmode in this case) so that the range of arguments isn't reduced when the inline is called for a narrower type. x87 and m68k are the only instruction sets I know to have the relevant instructions for expanding the expm1 / log1p operations inline, so other than for hypot this is a case of something theoretically generic but not so practically useful to make generic.
Author: uros Date: Fri Dec 21 13:30:58 2018 New Revision: 267325 URL: https://gcc.gnu.org/viewcvs?rev=267325&root=gcc&view=rev Log: PR target/88556 * internal-fn.def (COSH): New. (SINH): Ditto. (TANH): Ditto. * optabs.def (cosh_optab): New. (sinh_optab): Ditto. (tanh_optab): Ditto. * config/i386/i386-protos.h (ix86_emit_i387_sinh): New prototype. (ix86_emit_i387_cosh): Ditto. (ix86_emit_i387_tanh): Ditto. * config/i386/i386.c (ix86_emit_i387_sinh): New function. (ix86_emit_i387_cosh): Ditto. (ix86_emit_i387_tanh): Ditto. * config/i386/i386.md (sinhxf2): New expander. (sinh<mode>2): Ditto. (coshxf2): Ditto. (cosh<mode>2): Ditto. (tanhxf2): Ditto. (tanh<mode>2): Ditto. Modified: trunk/gcc/ChangeLog trunk/gcc/config/i386/i386-protos.h trunk/gcc/config/i386/i386.c trunk/gcc/config/i386/i386.md trunk/gcc/internal-fn.def trunk/gcc/optabs.def