Bug 88556 - Inline built-in sinh, cosh, tanh for -ffast-math
Summary: Inline built-in sinh, cosh, tanh 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-19 21:10 UTC by Joseph S. Myers
Modified: 2023-07-22 02:54 UTC (History)
0 users

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-19 21:10:00 UTC
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.
Comment 1 Richard Biener 2018-12-20 08:48:24 UTC
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?
Comment 2 jsm-csl@polyomino.org.uk 2018-12-20 21:35:30 UTC
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.
Comment 3 uros 2018-12-21 13:31:38 UTC
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