aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meissner <meissner@linux.vnet.ibm.com>2017-07-07 18:43:55 +0000
committerMichael Meissner <meissner@gcc.gnu.org>2017-07-07 18:43:55 +0000
commit57f49e990f52ebdd3cb4a5be4e87a2301fed1a1a (patch)
tree0571c2b8c4e497a91406f655fe819736cfbbe596
parent6a69355ccf7c05c452ff1bea1fac1508d44bec5c (diff)
downloadgcc-57f49e990f52ebdd3cb4a5be4e87a2301fed1a1a.zip
gcc-57f49e990f52ebdd3cb4a5be4e87a2301fed1a1a.tar.gz
gcc-57f49e990f52ebdd3cb4a5be4e87a2301fed1a1a.tar.bz2
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 <meissner@linux.vnet.ibm.com> * 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 <meissner@linux.vnet.ibm.com> * 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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/rs6000/rs6000.c37
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/powerpc/clone1.c1
-rw-r--r--gcc/testsuite/gcc.target/powerpc/clone2.c31
5 files changed, 56 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 85cb864..dbb5191 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
2017-07-07 Michael Meissner <meissner@linux.vnet.ibm.com>
+ * 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 200f43a..10c5521 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 cc0e5b8..b2e43ef 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2017-07-07 Michael Meissner <meissner@linux.vnet.ibm.com>
+ * 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 5c69db8..eb13a7b2 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 0000000..ecad5eb
--- /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 <stddef.h>
+#include <stdlib.h>
+
+/* 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;
+}