From 57f49e990f52ebdd3cb4a5be4e87a2301fed1a1a Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Fri, 7 Jul 2017 18:43:55 +0000 Subject: [PATCH] rs6000.c (rs6000_get_function_versions_dispatcher): Add warning if GCC was not configured to link against a GLIBC that exports the... [gcc] 2017-07-07 Michael Meissner * config/rs6000/rs6000.c (rs6000_get_function_versions_dispatcher): Add warning if GCC was not configured to link against a GLIBC that exports the hardware capability bits. (make_resolver_func): Make resolver function private and not a COMDAT function. Create the name with clone_function_name instead of make_unique_name. [gcc/testsuite] 2017-07-07 Michael Meissner * gcc.target/powerpc/clone1.c: Add check to make sure the __builtin_cpu_supports function is fully supported. * gcc.target/powerpc/clone2.c: New runtime test for target_clones. From-SVN: r250055 --- gcc/ChangeLog | 7 +++++ gcc/config/rs6000/rs6000.c | 37 ++++++++--------------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.target/powerpc/clone1.c | 1 + gcc/testsuite/gcc.target/powerpc/clone2.c | 31 +++++++++++++++++++ 5 files changed, 56 insertions(+), 25 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/clone2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 85cb86409b4..dbb51913ecf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2017-07-07 Michael Meissner + * config/rs6000/rs6000.c (rs6000_get_function_versions_dispatcher): + Add warning if GCC was not configured to link against a GLIBC that + exports the hardware capability bits. + (make_resolver_func): Make resolver function private and not a + COMDAT function. Create the name with clone_function_name instead + of make_unique_name. + PR target/81348 * config/rs6000/rs6000.md (HI sign_extend splitter): Use the correct operand in doing the split. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 200f43acde8..10c552152a4 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -37283,6 +37283,12 @@ rs6000_get_function_versions_dispatcher (void *decl) default_node = default_version_info->this_node; +#ifndef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB + warning_at (DECL_SOURCE_LOCATION (default_node->decl), 0, + "target_clone needs GLIBC (2.23 and newer) to export hardware " + "capability bits"); +#endif + if (targetm.has_ifunc_p ()) { struct cgraph_function_version_info *it_v = NULL; @@ -37328,29 +37334,19 @@ make_resolver_func (const tree default_decl, const tree dispatch_decl, basic_block *empty_bb) { - /* IFUNC's have to be globally visible. So, if the default_decl is - not, then the name of the IFUNC should be made unique. */ - bool is_uniq = (TREE_PUBLIC (default_decl) == 0); - - /* Append the filename to the resolver function if the versions are - not externally visible. This is because the resolver function has - to be externally visible for the loader to find it. So, appending - the filename will prevent conflicts with a resolver function from - another module which is based on the same version name. */ - char *resolver_name = make_unique_name (default_decl, "resolver", is_uniq); - - /* The resolver function should return a (void *). */ + /* Make the resolver function static. The resolver function returns + void *. */ + tree decl_name = clone_function_name (default_decl, "resolver"); + const char *resolver_name = IDENTIFIER_POINTER (decl_name); tree type = build_function_type_list (ptr_type_node, NULL_TREE); tree decl = build_fn_decl (resolver_name, type); - tree decl_name = get_identifier (resolver_name); SET_DECL_ASSEMBLER_NAME (decl, decl_name); DECL_NAME (decl) = decl_name; TREE_USED (decl) = 1; DECL_ARTIFICIAL (decl) = 1; DECL_IGNORED_P (decl) = 0; - /* IFUNC resolvers have to be externally visible. */ - TREE_PUBLIC (decl) = 1; + TREE_PUBLIC (decl) = 0; DECL_UNINLINABLE (decl) = 1; /* Resolver is not external, body is generated. */ @@ -37361,15 +37357,6 @@ make_resolver_func (const tree default_decl, DECL_INITIAL (decl) = make_node (BLOCK); DECL_STATIC_CONSTRUCTOR (decl) = 0; - if (DECL_COMDAT_GROUP (default_decl) || TREE_PUBLIC (default_decl)) - { - /* In this case, each translation unit with a call to this - versioned function will put out a resolver. Ensure it - is comdat to keep just one copy. */ - DECL_COMDAT (decl) = 1; - make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl)); - } - /* Build result decl and add to function_decl. */ tree t = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, ptr_type_node); DECL_ARTIFICIAL (t) = 1; @@ -37391,7 +37378,7 @@ make_resolver_func (const tree default_decl, = make_attribute ("ifunc", resolver_name, DECL_ATTRIBUTES (dispatch_decl)); cgraph_node::create_same_body_alias (dispatch_decl, decl); - XDELETEVEC (resolver_name); + return decl; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cc0e5b89b23..b2e43ef08a0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2017-07-07 Michael Meissner + * gcc.target/powerpc/clone1.c: Add check to make sure the + __builtin_cpu_supports function is fully supported. + * gcc.target/powerpc/clone2.c: New runtime test for + target_clones. + PR target/81348 * gcc.target/powerpc/pr81348.c: New test. diff --git a/gcc/testsuite/gcc.target/powerpc/clone1.c b/gcc/testsuite/gcc.target/powerpc/clone1.c index 5c69db8e217..eb13a7b2dbd 100644 --- a/gcc/testsuite/gcc.target/powerpc/clone1.c +++ b/gcc/testsuite/gcc.target/powerpc/clone1.c @@ -2,6 +2,7 @@ /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ /* { dg-options "-mcpu=power8 -O2" } */ /* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-require-effective-target ppc_cpu_supports_hw } */ /* Power9 (aka, ISA 3.0) has a MODSD instruction to do modulus, while Power8 (aka, ISA 2.07) has to do modulus with divide and multiply. Make sure diff --git a/gcc/testsuite/gcc.target/powerpc/clone2.c b/gcc/testsuite/gcc.target/powerpc/clone2.c new file mode 100644 index 00000000000..ecad5eb8e29 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/clone2.c @@ -0,0 +1,31 @@ +/* { dg-do run { target { powerpc*-*-linux* } } } */ +/* { dg-options "-mvsx -O2" } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-require-effective-target ppc_cpu_supports_hw } */ + +#include +#include + +/* Power9 (aka, ISA 3.0) has a MODSD instruction to do modulus, while Power8 + (aka, ISA 2.07) has to do modulus with divide and multiply. Make sure that + the basic support for target_clones runs. + + Restrict ourselves to Linux, since IFUNC might not be supported in other + operating systems. */ + +__attribute__((__target_clones__("cpu=power9,default"))) +long mod_func (long a, long b) +{ + return a % b; +} + +#define X 53L +#define Y 7L +int +main (void) +{ + if (mod_func (X, Y) != (X % Y)) + abort (); + + return 0; +} -- 2.30.2