diff mbox series

[nvptx] return true in libc_has_function for function_sincos

Message ID dc668312-cfc4-e029-81f6-fd3a84a2c4b8@codesourcery.com
State New
Headers show
Series [nvptx] return true in libc_has_function for function_sincos | expand

Commit Message

Tobias Burnus Sept. 26, 2020, 4:47 p.m. UTC
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
diff mbox series

Patch

[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"