GCC should support inline code generation for asinh, acosh, atanh 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 asinhl is slightly reduced. */ __inline_mathcodeNP (asinh, __x, \ register long double __y = __fabsl (__x); \ return (log1pl (__y * __y / (__libc_sqrtl (__y * __y + 1.0) + 1.0) + __y) \ * __sgn1l (__x))) __inline_mathcodeNP (acosh, __x, \ return logl (__x + __libc_sqrtl (__x - 1.0) * __libc_sqrtl (__x + 1.0))) __inline_mathcodeNP (atanh, __x, \ register long double __y = __fabsl (__x); \ return -0.5 * log1pl (-(__y + __y) / (1.0 + __y)) * __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 logl / log1pl 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). (__sgn1l is another inline function, copying the sign of x to the value 1.0L.)
(In reply to Joseph S. Myers from comment #0) > GCC should support inline code generation for asinh, acosh, atanh 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 asinhl is slightly reduced. > */ > __inline_mathcodeNP (asinh, __x, \ > register long double __y = __fabsl (__x); \ > return (log1pl (__y * __y / (__libc_sqrtl (__y * __y + 1.0) + 1.0) + __y) > \ > * __sgn1l (__x))) > > __inline_mathcodeNP (acosh, __x, \ > return logl (__x + __libc_sqrtl (__x - 1.0) * __libc_sqrtl (__x + 1.0))) > > __inline_mathcodeNP (atanh, __x, \ > register long double __y = __fabsl (__x); \ > return -0.5 * log1pl (-(__y + __y) / (1.0 + __y)) * __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 logl / log1pl 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). (__sgn1l is another inline function, copying > the sign of x to the value 1.0L.) Can you please advise, which would be appropirate conditions? I think that they should be similar to hypot conditions - flag_finite_math_only and flag_unsafe_math_optimizations. The x87 expansion is valid for float and double functions, we should leave out long double variant, even with flag_unsafe_math_optimizations.
I think flag_unsafe_math_optimizations is generally appropriate for these; asinh needs flag_finite_math_only as well (because an Inf argument would result in Inf / Inf) but neither of the others should.
Author: uros Date: Mon Dec 17 15:46:20 2018 New Revision: 267204 URL: https://gcc.gnu.org/viewcvs?rev=267204&root=gcc&view=rev Log: PR target/88502 * internal-fn.def (ACOSH): New. (ASINH): Ditto. (ATANH): Ditto. * optabs.def (acosh_optab): New. (asinh_optab): Ditto. (atanh_optab): Ditto. * config/i386/i386-protos.h (ix86_emit_i387_asinh): New prototype. (ix86_emit_i387_acosh): Ditto. (ix86_emit_i387_atanh): Ditto. * config/i386/i386.c (ix86_emit_i387_asinh): New function. (ix86_emit_i387_acosh): Ditto. (ix86_emit_i387_atanh): Ditto. * config/i386/i386.md (asinhxf2): New expander. (asinh<mode>2): Ditto. (acoshxf2): Ditto. (acosh<mode>2): Ditto. (atanhxf2): Ditto. (atanh<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