Found when looking at PR97203 (but having no effect there).
The GCC ME optimizes with -O1 (or higher) the a = sinf(x) b = cosf(x) to __builtin_cexpi(x, &a, &b) (...i as in internal; like cexp(z) but with with __real__ z == 0) In expand_builtin_cexpi, that is handles as: if (optab_handler (sincos_optab, mode) != CODE_FOR_nothing) ... else if (targetm.libc_has_function (function_sincos)) ... else fn = builtin_decl_explicit (BUILT_IN_CEXPF); And the latter is done. As newlib's cexpf does not know that __real__ z == 0, it calculates 'r = expf (__real__ z)' before invoking sinf and cosf on __imag__ z. Thus, it is much faster to call 'sincosf', which also exists in newlib. Solution: Return true for targetm.libc_has_function (function_sincos). NOTE: With -funsafe-math-optimizations (-O0 or higher), sinf/cosf and sincosf invoke .sin.approx/.cos/.approx instead of doing a library call. OK? Tobias ----------------- Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter
[nvptx] return true in libc_has_function for function_sincos gcc/ChangeLog: * config/nvptx/nvptx.c (nvptx_libc_has_function): New. (TARGET_LIBC_HAS_FUNCTION): Redefine to new func. diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c index 54b1fdf669b..d4b0de30ff1 100644 --- a/gcc/config/nvptx/nvptx.c +++ b/gcc/config/nvptx/nvptx.c @@ -6536,6 +6536,21 @@ nvptx_set_current_function (tree fndecl) oacc_bcast_partition = 0; } +/* By default we assume that c99 functions are present at the runtime, + including sincos which is excluded in default_libc_has_function. */ +bool +nvptx_libc_has_function (enum function_class fn_class) +{ + if (fn_class == function_c94 + || fn_class == function_c99_misc + || fn_class == function_c99_math_complex + || fn_class == function_sincos) + return true; + + return false; +} + + #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE nvptx_option_override @@ -6681,6 +6696,9 @@ nvptx_set_current_function (tree fndecl) #undef TARGET_SET_CURRENT_FUNCTION #define TARGET_SET_CURRENT_FUNCTION nvptx_set_current_function +#undef TARGET_LIBC_HAS_FUNCTION +#define TARGET_LIBC_HAS_FUNCTION nvptx_libc_has_function + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-nvptx.h"