[PATCH] Add type arg to TARGET_LIBC_HAS_FUNCTION
Richard Biener
richard.guenther@gmail.com
Tue Sep 29 06:59:12 GMT 2020
On Mon, Sep 28, 2020 at 7:28 PM Tom de Vries <tdevries@suse.de> wrote:
>
> [ was: Re: [Patch][nvptx] return true in libc_has_function for
> function_sincos ]
>
> On 9/26/20 6:47 PM, Tobias Burnus wrote:
> > 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.
>
> This version takes care to enable sincos and sincosf, but not sincosl.
>
> Target hook changes OK for trunk?
@@ -9770,7 +9770,7 @@ fold_builtin_sincos (location_t loc,
}
if (!call)
{
- if (!targetm.libc_has_function (function_c99_math_complex)
+ if (!targetm.libc_has_function (function_c99_math_complex, NULL_TREE)
why pass NULL_TREE and not 'type' here?
|| !builtin_decl_implicit_p (fn))
return NULL_TREE;
similar for the builtins.def change for the cases where math functions
are affected? I guess it's a bit awkward to make it work there, so OK.
bool
-darwin_libc_has_function (enum function_class fn_class)
+darwin_libc_has_function (enum function_class fn_class, tree type)
{
- if (fn_class == function_sincos)
+ if (type != NULL_TREE)
+ {
+ switch (fn_class)
+ {
+ case function_sincos:
+ break;
+ default:
+ /* Not implemented. */
+ gcc_unreachable ();
+ }
+ }
huh. I think special-casing this just for sincos is a bit awkward,
esp. ICEing for other queries with a type. Specifically
-@deftypefn {Target Hook} bool TARGET_LIBC_HAS_FUNCTION (enum
function_class @var{fn_class})
+@deftypefn {Target Hook} bool TARGET_LIBC_HAS_FUNCTION (enum
function_class @var{fn_class}, tree @var{type})
This hook determines whether a function from a class of functions
-@var{fn_class} is present in the target C library.
+@var{fn_class} is present in the target C library. The @var{type} argument
+can be used to distinguish between float, double and long double versions.
@end deftypefn
This doesn't mention we'll ICE for anything but sincos. A sensible
semantics would be that if TYPE is NULL the caller asks for support
for all standard (float, double, long double) types while with TYPE
non-NULL it can ask for a specific type including for example the
new _FloatN, etc. types.
Richard.
> Thanks,
> - Tom
More information about the Gcc-patches
mailing list