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)