rs6000.c (rs6000_get_function_versions_dispatcher): Add warning if GCC was not config...
authorMichael Meissner <meissner@linux.vnet.ibm.com>
Fri, 7 Jul 2017 18:43:55 +0000 (18:43 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Fri, 7 Jul 2017 18:43:55 +0000 (18:43 +0000)
[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

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/clone1.c
gcc/testsuite/gcc.target/powerpc/clone2.c [new file with mode: 0644]

index 85cb86409b49e9a8f1c670e8f265ece3cda26364..dbb51913ecfec52f3563a3b4146384e6bb071b89 100644 (file)
@@ -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.
index 200f43acde857e9763df5343bb6c01c8ff9e97fb..10c552152a4503636ca4fc1f6801c07a7357158e 100644 (file)
@@ -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;
 }
 
index cc0e5b89b23b7a8d8c27f6b4e7c2248ad72fc228..b2e43ef08a0e22309dc43ee8d22325d4995d2faa 100644 (file)
@@ -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.
 
index 5c69db8e217f90448b43fc99b9bfb6d4c7610698..eb13a7b2dbd42c9294cde1b13f51c1523f3c2442 100644 (file)
@@ -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 (file)
index 0000000..ecad5eb
--- /dev/null
@@ -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;
+}