Bug 88502 - Inline built-in asinh, acosh, atanh for -ffast-math
Summary: Inline built-in asinh, acosh, atanh for -ffast-math
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 9.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2018-12-14 21:24 UTC by Joseph S. Myers
Modified: 2023-07-22 02:53 UTC (History)
1 user (show)

See Also:
Host:
Target: i?86-*-*
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Joseph S. Myers 2018-12-14 21:24:00 UTC
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.)
Comment 1 Uroš Bizjak 2018-12-15 10:28:14 UTC
(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.
Comment 2 Joseph S. Myers 2018-12-15 13:42:57 UTC
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.
Comment 3 uros 2018-12-17 15:46:55 UTC
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