https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90500

--- Comment #13 from Guobing <neochen.life at aliyun dot com> ---
(In reply to Martin Liška from comment #12)
> > The background is that, we want to try optimize libm with avx2/avx512, and
> > found that not all the libm math functions will have benefit when we
> > generally use 'arch=haswell' or 'arch=skylake-avx512' to compile libm. So we
> > picked those 'good' libm math functions to add FMV attribute like
> > target_clone("default", "arch=haswell", "arch=skylake-avx512") to get
> > performance benefit. The alias is used in libm code by default. I have no
> > idea why these two are conflicting that not allowed by GCC9.
> 
> That makes sense. Based on the test-case you provided, you just want:
> 
> __attribute__((target_clones("default", "arch=haswell",
> "arch=skylake-avx512")))
> double
> __tanh (double x)
> {
>   double t, z;
>   int32_t jx, ix, lx;
> 
> 
>   do { ieee_double_shape_type ew_u; ew_u.value = (x); (jx) = ew_u.parts.msw;
> (lx) = ew_u.parts.lsw; } while (0);
>   ix = jx & 0x7fffffff;
> ...
> }
> 
> extern __typeof (__tanh) tanh __attribute__ ((weak, alias ("__tanh"))); //
> __attribute__ ((__copy__ (__tanh)));
> 
> You don't want to use __copy__ attribute because it's responsible for
> copying of target_clone attribute to the alias.
> And it does not make sense to create clones of an alias.

The copy is from alias used by libm by default (Below I paste the src code), I
cannot remove this copy seems. How can I then to use FMV for this function?

__attribute__((target_clones("default", "arch=haswell", "arch=broadwell"
,"arch=skylake", "arch=skylake-avx512")))
double
__tanh (double x)
{
  double t, z;
  int32_t jx, ix, lx;

  /* High word of |x|. */
  EXTRACT_WORDS (jx, lx, x);
  ix = jx & 0x7fffffff;

  /* x is INF or NaN */
  if (ix >= 0x7ff00000)
    {
      if (jx >= 0)
        return one / x + one;               /* tanh(+-inf)=+-1 */
      else
        return one / x - one;               /* tanh(NaN) = NaN */
    }

  /* |x| < 22 */
  if (ix < 0x40360000)                  /* |x|<22 */
    {
      if ((ix | lx) == 0)
        return x;                       /* x == +-0 */
      if (ix < 0x3c800000)              /* |x|<2**-55 */
        {
          math_check_force_underflow (x);
          return x * (one + x);           /* tanh(small) = small */
        }
      if (ix >= 0x3ff00000)             /* |x|>=1  */
        {
          t = __expm1 (two * fabs (x));
          z = one - two / (t + two);
        }
      else
        {
          t = __expm1 (-two * fabs (x));
          z = -t / (t + two);
        }
      /* |x| > 22, return +-1 */
    }
  else
    {
      z = one - tiny;                   /* raised inexact flag */
    }
  return (jx >= 0) ? z : -z;
}
libm_alias_double (__tanh, tanh)

Reply via email to