mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-17 05:00:25 +08:00
[nvptx] Add type arg to TARGET_LIBC_HAS_FUNCTION
GCC has a target hook TARGET_LIBC_HAS_FUNCTION, which tells the compiler which functions it can expect to be present in libc. The default target hook does not include the sincos functions. The nvptx port of newlib does include sincos and sincosf, but not sincosl. The target hook TARGET_LIBC_HAS_FUNCTION does not distinguish between sincos, sincosf and sincosl, so if we enable it for the sincos functions, then for test.c: ... long double x, a, b; int main (void) { x = 0.5; a = sinl (x); b = cosl (x); printf ("a: %f\n", (double)a); printf ("b: %f\n", (double)b); return 0; } ... we introduce a regression: ... $ gcc test.c -lm -O2 unresolved symbol sincosl collect2: error: ld returned 1 exit status ... Add a type argument to target hook TARGET_LIBC_HAS_FUNCTION_TYPE, and use it in nvptx_libc_has_function_type to enable sincos and sincosf, but not sincosl. Build and reg-tested on x86_64-linux. Build and tested on nvptx. gcc/ChangeLog: 2020-09-28 Tobias Burnus <tobias@codesourcery.com> Tom de Vries <tdevries@suse.de> * builtins.c (expand_builtin_cexpi, fold_builtin_sincos): Update targetm.libc_has_function call. * builtins.def (DEF_C94_BUILTIN, DEF_C99_BUILTIN, DEF_C11_BUILTIN): (DEF_C2X_BUILTIN, DEF_C99_COMPL_BUILTIN, DEF_C99_C90RES_BUILTIN): Same. * config/darwin-protos.h (darwin_libc_has_function): Update prototype. * config/darwin.c (darwin_libc_has_function): Add arg. * config/linux-protos.h (linux_libc_has_function): Update prototype. * config/linux.c (linux_libc_has_function): Add arg. * config/i386/i386.c (ix86_libc_has_function): Update targetm.libc_has_function call. * config/nvptx/nvptx.c (nvptx_libc_has_function): New function. (TARGET_LIBC_HAS_FUNCTION): Redefine to nvptx_libc_has_function. * convert.c (convert_to_integer_1): Update targetm.libc_has_function call. * match.pd: Same. * target.def (libc_has_function): Add arg. * doc/tm.texi: Regenerate. * targhooks.c (default_libc_has_function, gnu_libc_has_function) (no_c99_libc_has_function): Add arg. * targhooks.h (default_libc_has_function, no_c99_libc_has_function) (gnu_libc_has_function): Update prototype. * tree-ssa-math-opts.c (pass_cse_sincos::execute): Update targetm.libc_has_function call. gcc/fortran/ChangeLog: 2020-09-30 Tom de Vries <tdevries@suse.de> * f95-lang.c (gfc_init_builtin_functions): Update targetm.libc_has_function call.
This commit is contained in:
parent
46183c96d2
commit
bae974e637
@ -2733,7 +2733,7 @@ expand_builtin_cexpi (tree exp, rtx target)
|
||||
/* Compute into op1 and op2. */
|
||||
expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
|
||||
}
|
||||
else if (targetm.libc_has_function (function_sincos))
|
||||
else if (targetm.libc_has_function (function_sincos, type))
|
||||
{
|
||||
tree call, fn = NULL_TREE;
|
||||
tree top1, top2;
|
||||
@ -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, type)
|
||||
|| !builtin_decl_implicit_p (fn))
|
||||
return NULL_TREE;
|
||||
fndecl = builtin_decl_explicit (fn);
|
||||
|
@ -138,34 +138,41 @@ along with GCC; see the file COPYING3. If not see
|
||||
#undef DEF_C94_BUILTIN
|
||||
#define DEF_C94_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, !flag_isoc94, ATTRS, targetm.libc_has_function (function_c94), true)
|
||||
true, true, !flag_isoc94, ATTRS, \
|
||||
targetm.libc_has_function (function_c94, NULL_TREE), true)
|
||||
|
||||
/* Like DEF_LIB_BUILTIN, except that the function is only a part of
|
||||
the standard in C99 or above. */
|
||||
#undef DEF_C99_BUILTIN
|
||||
#define DEF_C99_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_misc), true)
|
||||
true, true, !flag_isoc99, ATTRS, \
|
||||
targetm.libc_has_function (function_c99_misc, NULL_TREE), true)
|
||||
|
||||
/* Like DEF_LIB_BUILTIN, except that the function is only a part of
|
||||
the standard in C11 or above. */
|
||||
#undef DEF_C11_BUILTIN
|
||||
#define DEF_C11_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, !flag_isoc11, ATTRS, targetm.libc_has_function (function_c11_misc), true)
|
||||
true, true, !flag_isoc11, ATTRS, \
|
||||
targetm.libc_has_function (function_c11_misc, NULL_TREE), true)
|
||||
|
||||
/* Like DEF_LIB_BUILTIN, except that the function is only a part of
|
||||
the standard in C2x or above. */
|
||||
#undef DEF_C2X_BUILTIN
|
||||
#define DEF_C2X_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, !flag_isoc2x, ATTRS, targetm.libc_has_function (function_c2x_misc), true)
|
||||
true, true, !flag_isoc2x, ATTRS, \
|
||||
targetm.libc_has_function (function_c2x_misc, NULL_TREE), true)
|
||||
|
||||
/* Like DEF_C99_BUILTIN, but for complex math functions. */
|
||||
#undef DEF_C99_COMPL_BUILTIN
|
||||
#define DEF_C99_COMPL_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_math_complex), true)
|
||||
true, true, !flag_isoc99, ATTRS, \
|
||||
targetm.libc_has_function (function_c99_math_complex, \
|
||||
NULL_TREE), \
|
||||
true)
|
||||
|
||||
/* Builtin that is specified by C99 and C90 reserve the name for future use.
|
||||
We can still recognize the builtin in C90 mode but we can't produce it
|
||||
@ -173,7 +180,8 @@ along with GCC; see the file COPYING3. If not see
|
||||
#undef DEF_C99_C90RES_BUILTIN
|
||||
#define DEF_C99_C90RES_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_misc), true)
|
||||
true, true, !flag_isoc99, ATTRS, \
|
||||
targetm.libc_has_function (function_c99_misc, NULL_TREE), true)
|
||||
|
||||
/* Builtin that C99 reserve the name for future use. We can still recognize
|
||||
the builtin in C99 mode but we can't produce it implicitly. */
|
||||
|
@ -125,6 +125,6 @@ extern bool darwin_kextabi_p (void);
|
||||
extern void darwin_override_options (void);
|
||||
extern void darwin_patch_builtins (void);
|
||||
extern void darwin_rename_builtins (void);
|
||||
extern bool darwin_libc_has_function (enum function_class fn_class);
|
||||
extern bool darwin_libc_has_function (enum function_class fn_class, tree);
|
||||
|
||||
#endif /* CONFIG_DARWIN_PROTOS_H */
|
||||
|
@ -3542,7 +3542,8 @@ darwin_rename_builtins (void)
|
||||
}
|
||||
|
||||
bool
|
||||
darwin_libc_has_function (enum function_class fn_class)
|
||||
darwin_libc_has_function (enum function_class fn_class,
|
||||
tree type ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (fn_class == function_sincos)
|
||||
return (strverscmp (darwin_macosx_version_min, "10.9") >= 0);
|
||||
|
@ -1484,7 +1484,7 @@ ix86_reg_parm_stack_space (const_tree fndecl)
|
||||
bool
|
||||
ix86_libc_has_function (enum function_class fn_class)
|
||||
{
|
||||
return targetm.libc_has_function (fn_class);
|
||||
return targetm.libc_has_function (fn_class, NULL_TREE);
|
||||
}
|
||||
|
||||
/* Returns value SYSV_ABI, MS_ABI dependent on fntype,
|
||||
|
@ -19,4 +19,4 @@ along with GCC; see the file COPYING3. If not see
|
||||
|
||||
extern bool linux_has_ifunc_p (void);
|
||||
|
||||
extern bool linux_libc_has_function (enum function_class fn_class);
|
||||
extern bool linux_libc_has_function (enum function_class fn_class, tree);
|
||||
|
@ -25,7 +25,8 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "linux-protos.h"
|
||||
|
||||
bool
|
||||
linux_libc_has_function (enum function_class fn_class)
|
||||
linux_libc_has_function (enum function_class fn_class,
|
||||
tree type ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (OPTION_GLIBC || OPTION_MUSL)
|
||||
return true;
|
||||
|
@ -6536,6 +6536,23 @@ nvptx_set_current_function (tree fndecl)
|
||||
oacc_bcast_partition = 0;
|
||||
}
|
||||
|
||||
/* Implement TARGET_LIBC_HAS_FUNCTION. */
|
||||
|
||||
bool
|
||||
nvptx_libc_has_function (enum function_class fn_class, tree type)
|
||||
{
|
||||
if (fn_class == function_sincos)
|
||||
{
|
||||
if (type != NULL_TREE)
|
||||
/* Currently, newlib does not support sincosl. */
|
||||
return type == float_type_node || type == double_type_node;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
return default_libc_has_function (fn_class, type);
|
||||
}
|
||||
|
||||
#undef TARGET_OPTION_OVERRIDE
|
||||
#define TARGET_OPTION_OVERRIDE nvptx_option_override
|
||||
|
||||
@ -6681,6 +6698,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"
|
||||
|
@ -501,7 +501,7 @@ convert_to_integer_1 (tree type, tree expr, bool dofold)
|
||||
CASE_FLT_FN (BUILT_IN_CEIL):
|
||||
CASE_FLT_FN_FLOATN_NX (BUILT_IN_CEIL):
|
||||
/* Only convert in ISO C99 mode. */
|
||||
if (!targetm.libc_has_function (function_c99_misc))
|
||||
if (!targetm.libc_has_function (function_c99_misc, intype))
|
||||
break;
|
||||
if (outprec < TYPE_PRECISION (integer_type_node)
|
||||
|| (outprec == TYPE_PRECISION (integer_type_node)
|
||||
@ -518,7 +518,7 @@ convert_to_integer_1 (tree type, tree expr, bool dofold)
|
||||
CASE_FLT_FN (BUILT_IN_FLOOR):
|
||||
CASE_FLT_FN_FLOATN_NX (BUILT_IN_FLOOR):
|
||||
/* Only convert in ISO C99 mode. */
|
||||
if (!targetm.libc_has_function (function_c99_misc))
|
||||
if (!targetm.libc_has_function (function_c99_misc, intype))
|
||||
break;
|
||||
if (outprec < TYPE_PRECISION (integer_type_node)
|
||||
|| (outprec == TYPE_PRECISION (integer_type_node)
|
||||
@ -535,7 +535,7 @@ convert_to_integer_1 (tree type, tree expr, bool dofold)
|
||||
CASE_FLT_FN (BUILT_IN_ROUND):
|
||||
CASE_FLT_FN_FLOATN_NX (BUILT_IN_ROUND):
|
||||
/* Only convert in ISO C99 mode and with -fno-math-errno. */
|
||||
if (!targetm.libc_has_function (function_c99_misc)
|
||||
if (!targetm.libc_has_function (function_c99_misc, intype)
|
||||
|| flag_errno_math)
|
||||
break;
|
||||
if (outprec < TYPE_PRECISION (integer_type_node)
|
||||
@ -559,7 +559,7 @@ convert_to_integer_1 (tree type, tree expr, bool dofold)
|
||||
CASE_FLT_FN (BUILT_IN_RINT):
|
||||
CASE_FLT_FN_FLOATN_NX (BUILT_IN_RINT):
|
||||
/* Only convert in ISO C99 mode and with -fno-math-errno. */
|
||||
if (!targetm.libc_has_function (function_c99_misc)
|
||||
if (!targetm.libc_has_function (function_c99_misc, intype)
|
||||
|| flag_errno_math)
|
||||
break;
|
||||
if (outprec < TYPE_PRECISION (integer_type_node)
|
||||
|
@ -5602,9 +5602,12 @@ refers to the global ``variable'' @code{errno}. (On certain systems,
|
||||
macro, a reasonable default is used.
|
||||
@end defmac
|
||||
|
||||
@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. If @var{type} is NULL,
|
||||
the caller asks for support for all standard (float, double, long double)
|
||||
types. If @var{type} is non-NULL, the caller asks for support for a
|
||||
specific type.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} bool TARGET_LIBC_HAS_FAST_FUNCTION (int @var{fcode})
|
||||
|
@ -881,7 +881,7 @@ gfc_init_builtin_functions (void)
|
||||
BUILT_IN_POWIF, "powif", ATTR_CONST_NOTHROW_LEAF_LIST);
|
||||
|
||||
|
||||
if (targetm.libc_has_function (function_c99_math_complex))
|
||||
if (targetm.libc_has_function (function_c99_math_complex, NULL_TREE))
|
||||
{
|
||||
gfc_define_builtin ("__builtin_cbrtl", mfunc_longdouble[0],
|
||||
BUILT_IN_CBRTL, "cbrtl",
|
||||
@ -903,7 +903,7 @@ gfc_init_builtin_functions (void)
|
||||
ATTR_CONST_NOTHROW_LEAF_LIST);
|
||||
}
|
||||
|
||||
if (targetm.libc_has_function (function_sincos))
|
||||
if (targetm.libc_has_function (function_sincos, NULL_TREE))
|
||||
{
|
||||
gfc_define_builtin ("__builtin_sincosl",
|
||||
func_longdouble_longdoublep_longdoublep,
|
||||
|
@ -5185,7 +5185,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
||||
(with {
|
||||
const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (@0);
|
||||
bool use_exp2 = false;
|
||||
if (targetm.libc_has_function (function_c99_misc)
|
||||
if (targetm.libc_has_function (function_c99_misc, TREE_TYPE (@0))
|
||||
&& value->cl == rvc_normal)
|
||||
{
|
||||
REAL_VALUE_TYPE frac_rvt = *value;
|
||||
@ -5484,7 +5484,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
||||
cexpis (CEXPI)
|
||||
(simplify
|
||||
(cexps compositional_complex@0)
|
||||
(if (targetm.libc_has_function (function_c99_math_complex))
|
||||
(if (targetm.libc_has_function (function_c99_math_complex, TREE_TYPE (@0)))
|
||||
(complex
|
||||
(mult (exps@1 (realpart @0)) (realpart (cexpis:type@2 (imagpart @0))))
|
||||
(mult @1 (imagpart @2)))))))
|
||||
@ -5536,7 +5536,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
||||
/* truncl(extend(x)) and trunc(extend(x)) -> extend(truncf(x)), etc.,
|
||||
if x is a float. */
|
||||
(if (optimize && canonicalize_math_p ()
|
||||
&& targetm.libc_has_function (function_c99_misc))
|
||||
&& targetm.libc_has_function (function_c99_misc, NULL_TREE))
|
||||
(simplify
|
||||
(froms (convert float_value_p@0))
|
||||
(convert (tos @0)))))
|
||||
|
@ -2618,8 +2618,11 @@ set via @code{__attribute__}.",
|
||||
DEFHOOK
|
||||
(libc_has_function,
|
||||
"This hook determines whether a function from a class of functions\n\
|
||||
@var{fn_class} is present in the target C library.",
|
||||
bool, (enum function_class fn_class),
|
||||
@var{fn_class} is present in the target C library. If @var{type} is NULL,\n\
|
||||
the caller asks for support for all standard (float, double, long double)\n\
|
||||
types. If @var{type} is non-NULL, the caller asks for support for a\n\
|
||||
specific type.",
|
||||
bool, (enum function_class fn_class, tree type),
|
||||
default_libc_has_function)
|
||||
|
||||
DEFHOOK
|
||||
|
@ -1641,7 +1641,8 @@ default_have_conditional_execution (void)
|
||||
/* By default we assume that c99 functions are present at the runtime,
|
||||
but sincos is not. */
|
||||
bool
|
||||
default_libc_has_function (enum function_class fn_class)
|
||||
default_libc_has_function (enum function_class fn_class,
|
||||
tree type ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (fn_class == function_c94
|
||||
|| fn_class == function_c99_misc
|
||||
@ -1660,13 +1661,15 @@ default_libc_has_fast_function (int fcode ATTRIBUTE_UNUSED)
|
||||
}
|
||||
|
||||
bool
|
||||
gnu_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED)
|
||||
gnu_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED,
|
||||
tree type ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
no_c99_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED)
|
||||
no_c99_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED,
|
||||
tree type ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -208,10 +208,10 @@ extern rtx default_addr_space_convert (rtx, tree, tree);
|
||||
extern unsigned int default_case_values_threshold (void);
|
||||
extern bool default_have_conditional_execution (void);
|
||||
|
||||
extern bool default_libc_has_function (enum function_class);
|
||||
extern bool default_libc_has_function (enum function_class, tree);
|
||||
extern bool default_libc_has_fast_function (int fcode);
|
||||
extern bool no_c99_libc_has_function (enum function_class);
|
||||
extern bool gnu_libc_has_function (enum function_class);
|
||||
extern bool no_c99_libc_has_function (enum function_class, tree);
|
||||
extern bool gnu_libc_has_function (enum function_class, tree);
|
||||
|
||||
extern tree default_builtin_tm_load_store (tree);
|
||||
|
||||
|
@ -2176,12 +2176,14 @@ pass_cse_sincos::execute (function *fun)
|
||||
CASE_CFN_COS:
|
||||
CASE_CFN_SIN:
|
||||
CASE_CFN_CEXPI:
|
||||
arg = gimple_call_arg (stmt, 0);
|
||||
/* Make sure we have either sincos or cexp. */
|
||||
if (!targetm.libc_has_function (function_c99_math_complex)
|
||||
&& !targetm.libc_has_function (function_sincos))
|
||||
if (!targetm.libc_has_function (function_c99_math_complex,
|
||||
TREE_TYPE (arg))
|
||||
&& !targetm.libc_has_function (function_sincos,
|
||||
TREE_TYPE (arg)))
|
||||
break;
|
||||
|
||||
arg = gimple_call_arg (stmt, 0);
|
||||
if (TREE_CODE (arg) == SSA_NAME)
|
||||
cfg_changed |= execute_cse_sincos_1 (arg);
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user