public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/aoliva/heads/testme)] [PR83782] ifunc: back-propagate ifunc_resolver to aliases
@ 2023-11-15  2:26 Alexandre Oliva
  0 siblings, 0 replies; 13+ messages in thread
From: Alexandre Oliva @ 2023-11-15  2:26 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:4df06fc448f742efca632308fba5450dbfea0b12

commit 4df06fc448f742efca632308fba5450dbfea0b12
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Tue Nov 14 22:15:37 2023 -0300

    [PR83782] ifunc: back-propagate ifunc_resolver to aliases
    
    gcc.target/i386/mvc10.c fails with -fPIE on ia32 because we omit the
    @PLT mark when calling an alias to an indirect function.  Such aliases
    aren't marked as ifunc_resolvers in the cgraph, so the test that would
    have forced the PLT call fails.
    
    I've arranged for ifunc_resolver to be back-propagated to aliases, and
    relaxed the test that required the ifunc attribute to be attached to
    directly the decl, rather than taken from an aliased decl, when the
    ifunc_resolver bit is set.
    
    
    for  gcc/ChangeLog
    
            PR target/83782
            * cgraph.h (symtab_node::set_ifunc_resolver): New, overloaded.
            Back-propagate flag to aliases.
            * cgraph.cc (cgraph_node::create): Use set_ifunc_resolver.
            (cgraph_node::create_alias): Likewise.
            * lto-cgraph.cc (input_node): Likewise.
            * multiple_target.cc (create_dispatcher_calls): Propagate to
            aliases when redirecting them.
            * symtab.cc (symtab_node::verify_base): Accept ifunc_resolver
            set in an alias to another ifunc_resolver nodes.
            (symtab_node::resolve_alias): Propagate ifunc_resolver from
            resolved target to alias.
            * varasm.cc (do_assemble_alias): Checking for the attribute.

Diff:
---
 gcc/cgraph.cc          |  4 ++--
 gcc/cgraph.h           | 13 +++++++++++++
 gcc/lto-cgraph.cc      |  2 +-
 gcc/multiple_target.cc |  2 ++
 gcc/symtab.cc          | 15 ++++++++++++++-
 gcc/varasm.cc          |  5 ++++-
 6 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index e41e5ad3ae7..046dadf53af 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -518,7 +518,7 @@ cgraph_node::create (tree decl)
     }
 
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
-    node->ifunc_resolver = true;
+    node->set_ifunc_resolver ();
 
   node->register_symbol ();
   maybe_record_nested_function (node);
@@ -576,7 +576,7 @@ cgraph_node::create_alias (tree alias, tree target)
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     alias_node->transparent_alias = alias_node->weakref = true;
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
-    alias_node->ifunc_resolver = true;
+    alias_node->set_ifunc_resolver ();
   return alias_node;
 }
 
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index cedaaac3a45..e118ac75121 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -471,6 +471,19 @@ public:
     return decl->decl_with_vis.symtab_node;
   }
 
+  /* Worked for the nonstatic set_ifunc_resolver, to vback-propagate
+     ifunc_resolver in the alias chain.  */
+  static bool set_ifunc_resolver (symtab_node *n, void * = NULL)
+  {
+    n->ifunc_resolver = true;
+    return false;
+  }
+
+  /* Set the ifunc_resolver bit in this node and in any aliases thereof.  */
+  void set_ifunc_resolver () {
+    call_for_symbol_and_aliases (set_ifunc_resolver, NULL, true);
+  }
+
   /* Try to find a symtab node for declaration DECL and if it does not
      exist or if it corresponds to an inline clone, create a new one.  */
   static inline symtab_node * get_create (tree node);
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index db6a22a444e..ce13271563f 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -1308,7 +1308,7 @@ input_node (struct lto_file_decl_data *file_data,
       node = symtab->create_empty ();
       node->decl = fn_decl;
       if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl)))
-	node->ifunc_resolver = 1;
+	node->set_ifunc_resolver ();
       node->register_symbol ();
     }
 
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index a2ed048d7dd..26c73d6a1e4 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -160,6 +160,8 @@ create_dispatcher_calls (struct cgraph_node *node)
 	      source->create_reference (inode, IPA_REF_ALIAS);
 	      if (inode->get_comdat_group ())
 		source->add_to_same_comdat_group (inode);
+	      if (!source->ifunc_resolver)
+		source->set_ifunc_resolver ();
 	    }
 	  else
 	    gcc_unreachable ();
diff --git a/gcc/symtab.cc b/gcc/symtab.cc
index 0470509a98d..b35b879028d 100644
--- a/gcc/symtab.cc
+++ b/gcc/symtab.cc
@@ -1109,9 +1109,19 @@ symtab_node::verify_base (void)
           error ("function symbol is not function");
           error_found = true;
 	}
+      /* If the ifunc attribute is present, the node must be marked as
+	 ifunc_resolver, but it may also be marked on a node that
+	 doesn't have the attribute, if it's an alias to another
+	 marked node.  The resolver node itself is an alias to the
+	 function that performs the resolution proper, and that
+	 function is not marked, but here we test other kinds of
+	 aliases, that alias the indirect function.  */
       else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
 		!= NULL)
-	       != dyn_cast <cgraph_node *> (this)->ifunc_resolver)
+	       ? !ifunc_resolver
+	       : ifunc_resolver
+	       ? !get_alias_target ()->ifunc_resolver
+	       : (alias && analyzed && get_alias_target ()->ifunc_resolver))
 	{
 	  error ("inconsistent %<ifunc%> attribute");
           error_found = true;
@@ -1879,6 +1889,9 @@ symtab_node::resolve_alias (symtab_node *target, bool transparent)
   if (target->implicit_section)
     call_for_symbol_and_aliases (set_implicit_section, NULL, true);
 
+  if (target->ifunc_resolver && !ifunc_resolver)
+    set_ifunc_resolver ();
+
   /* Alias targets become redundant after alias is resolved into an reference.
      We do not want to keep it around or we would have to mind updating them
      when renaming symbols.  */
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 6ae35edc5ae..c6aa7c1745d 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -6262,7 +6262,10 @@ do_assemble_alias (tree decl, tree target)
       maybe_assemble_visibility (decl);
     }
   if (TREE_CODE (decl) == FUNCTION_DECL
-      && cgraph_node::get (decl)->ifunc_resolver)
+      && cgraph_node::get (decl)->ifunc_resolver
+      /* Aliases to the ifunc decl will also have the ifunc_resolver
+	 bit set, so check that this is the ifunc declaration.  */
+      && lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
     {
 #if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
       if (targetm.has_ifunc_p ())

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] [PR83782] ifunc: back-propagate ifunc_resolver to aliases
@ 2024-10-29 21:27 Alexandre Oliva
  0 siblings, 0 replies; 13+ messages in thread
From: Alexandre Oliva @ 2024-10-29 21:27 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:44091b3480985244d5d981886f3c5624e8ca1571

commit 44091b3480985244d5d981886f3c5624e8ca1571
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Thu Dec 14 03:21:28 2023 -0300

    [PR83782] ifunc: back-propagate ifunc_resolver to aliases
    
    gcc.target/i386/mvc10.c fails with -fPIE on ia32 because we omit the
    @PLT mark when calling an alias to an indirect function.  Such aliases
    aren't marked as ifunc_resolvers in the cgraph, so the test that would
    have forced the PLT call fails.
    
    I've arranged for ifunc_resolver to be back-propagated to aliases, and
    relaxed the test that required the ifunc attribute to be attached to
    directly the decl, rather than taken from an aliased decl, when the
    ifunc_resolver bit is set.
    
    
    for  gcc/ChangeLog
    
            PR target/83782
            * cgraph.h (symtab_node::set_ifunc_resolver): New, overloaded.
            Back-propagate flag to aliases.
            * cgraph.cc (cgraph_node::create): Use set_ifunc_resolver.
            (cgraph_node::create_alias): Likewise.
            * lto-cgraph.cc (input_node): Likewise.
            * multiple_target.cc (create_dispatcher_calls): Propagate to
            aliases when redirecting them.
            * symtab.cc (symtab_node::verify_base): Accept ifunc_resolver
            set in an alias to another ifunc_resolver nodes.
            (symtab_node::resolve_alias): Propagate ifunc_resolver from
            resolved target to alias.
            * varasm.cc (do_assemble_alias): Checking for the attribute.

Diff:
---
 gcc/cgraph.cc          |  4 ++--
 gcc/cgraph.h           | 13 +++++++++++++
 gcc/lto-cgraph.cc      |  2 +-
 gcc/multiple_target.cc |  2 ++
 gcc/symtab.cc          | 15 ++++++++++++++-
 gcc/varasm.cc          |  5 ++++-
 6 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index b5d096d530c0..9f6493c9b156 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -520,7 +520,7 @@ cgraph_node::create (tree decl)
     }
 
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
-    node->ifunc_resolver = true;
+    node->set_ifunc_resolver ();
 
   node->register_symbol ();
   maybe_record_nested_function (node);
@@ -578,7 +578,7 @@ cgraph_node::create_alias (tree alias, tree target)
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     alias_node->transparent_alias = alias_node->weakref = true;
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
-    alias_node->ifunc_resolver = true;
+    alias_node->set_ifunc_resolver ();
   return alias_node;
 }
 
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index a8c3224802c1..261d4745d142 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -471,6 +471,19 @@ public:
     return decl->decl_with_vis.symtab_node;
   }
 
+  /* Worked for the nonstatic set_ifunc_resolver, to vback-propagate
+     ifunc_resolver in the alias chain.  */
+  static bool set_ifunc_resolver (symtab_node *n, void * = NULL)
+  {
+    n->ifunc_resolver = true;
+    return false;
+  }
+
+  /* Set the ifunc_resolver bit in this node and in any aliases thereof.  */
+  void set_ifunc_resolver () {
+    call_for_symbol_and_aliases (set_ifunc_resolver, NULL, true);
+  }
+
   /* Try to find a symtab node for declaration DECL and if it does not
      exist or if it corresponds to an inline clone, create a new one.  */
   static inline symtab_node * get_create (tree node);
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index 1d4311a8832b..e8af5ea14a98 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -1299,7 +1299,7 @@ input_node (struct lto_file_decl_data *file_data,
       node = symtab->create_empty ();
       node->decl = fn_decl;
       if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl)))
-	node->ifunc_resolver = 1;
+	node->set_ifunc_resolver ();
       node->register_symbol ();
     }
 
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index 1fdd279da04a..1deaa3d3c3ec 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -156,6 +156,8 @@ create_dispatcher_calls (struct cgraph_node *node)
 	      source->create_reference (inode, IPA_REF_ALIAS);
 	      if (inode->get_comdat_group ())
 		source->add_to_same_comdat_group (inode);
+	      if (!source->ifunc_resolver)
+		source->set_ifunc_resolver ();
 	    }
 	  else
 	    gcc_unreachable ();
diff --git a/gcc/symtab.cc b/gcc/symtab.cc
index 3b018ab3ea21..08607497970f 100644
--- a/gcc/symtab.cc
+++ b/gcc/symtab.cc
@@ -1109,9 +1109,19 @@ symtab_node::verify_base (void)
           error ("function symbol is not function");
           error_found = true;
 	}
+      /* If the ifunc attribute is present, the node must be marked as
+	 ifunc_resolver, but it may also be marked on a node that
+	 doesn't have the attribute, if it's an alias to another
+	 marked node.  The resolver node itself is an alias to the
+	 function that performs the resolution proper, and that
+	 function is not marked, but here we test other kinds of
+	 aliases, that alias the indirect function.  */
       else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
 		!= NULL)
-	       != dyn_cast <cgraph_node *> (this)->ifunc_resolver)
+	       ? !ifunc_resolver
+	       : ifunc_resolver
+	       ? !get_alias_target ()->ifunc_resolver
+	       : (alias && analyzed && get_alias_target ()->ifunc_resolver))
 	{
 	  error ("inconsistent %<ifunc%> attribute");
           error_found = true;
@@ -1971,6 +1981,9 @@ symtab_node::resolve_alias (symtab_node *target, bool transparent)
   if (target->implicit_section)
     call_for_symbol_and_aliases (set_implicit_section, NULL, true);
 
+  if (target->ifunc_resolver && !ifunc_resolver)
+    set_ifunc_resolver ();
+
   /* Alias targets become redundant after alias is resolved into an reference.
      We do not want to keep it around or we would have to mind updating them
      when renaming symbols.  */
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index c25400554216..6cd922e45881 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -6345,7 +6345,10 @@ do_assemble_alias (tree decl, tree target)
       maybe_assemble_visibility (decl);
     }
   if (TREE_CODE (decl) == FUNCTION_DECL
-      && cgraph_node::get (decl)->ifunc_resolver)
+      && cgraph_node::get (decl)->ifunc_resolver
+      /* Aliases to the ifunc decl will also have the ifunc_resolver
+	 bit set, so check that this is the ifunc declaration.  */
+      && lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
     {
 #if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
       if (targetm.has_ifunc_p ())

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] [PR83782] ifunc: back-propagate ifunc_resolver to aliases
@ 2023-12-14 16:26 Alexandre Oliva
  0 siblings, 0 replies; 13+ messages in thread
From: Alexandre Oliva @ 2023-12-14 16:26 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:98a6ed3a61e77b9f24ed165f7cb1301da0dcc18e

commit 98a6ed3a61e77b9f24ed165f7cb1301da0dcc18e
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Thu Dec 14 03:21:28 2023 -0300

    [PR83782] ifunc: back-propagate ifunc_resolver to aliases
    
    gcc.target/i386/mvc10.c fails with -fPIE on ia32 because we omit the
    @PLT mark when calling an alias to an indirect function.  Such aliases
    aren't marked as ifunc_resolvers in the cgraph, so the test that would
    have forced the PLT call fails.
    
    I've arranged for ifunc_resolver to be back-propagated to aliases, and
    relaxed the test that required the ifunc attribute to be attached to
    directly the decl, rather than taken from an aliased decl, when the
    ifunc_resolver bit is set.
    
    
    for  gcc/ChangeLog
    
            PR target/83782
            * cgraph.h (symtab_node::set_ifunc_resolver): New, overloaded.
            Back-propagate flag to aliases.
            * cgraph.cc (cgraph_node::create): Use set_ifunc_resolver.
            (cgraph_node::create_alias): Likewise.
            * lto-cgraph.cc (input_node): Likewise.
            * multiple_target.cc (create_dispatcher_calls): Propagate to
            aliases when redirecting them.
            * symtab.cc (symtab_node::verify_base): Accept ifunc_resolver
            set in an alias to another ifunc_resolver nodes.
            (symtab_node::resolve_alias): Propagate ifunc_resolver from
            resolved target to alias.
            * varasm.cc (do_assemble_alias): Checking for the attribute.

Diff:
---
 gcc/cgraph.cc          |  4 ++--
 gcc/cgraph.h           | 13 +++++++++++++
 gcc/lto-cgraph.cc      |  2 +-
 gcc/multiple_target.cc |  2 ++
 gcc/symtab.cc          | 15 ++++++++++++++-
 gcc/varasm.cc          |  5 ++++-
 6 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 0bef2179e89..cf36d622e20 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -518,7 +518,7 @@ cgraph_node::create (tree decl)
     }
 
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
-    node->ifunc_resolver = true;
+    node->set_ifunc_resolver ();
 
   node->register_symbol ();
   maybe_record_nested_function (node);
@@ -578,7 +578,7 @@ cgraph_node::create_alias (tree alias, tree target)
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     alias_node->transparent_alias = alias_node->weakref = true;
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
-    alias_node->ifunc_resolver = true;
+    alias_node->set_ifunc_resolver ();
   return alias_node;
 }
 
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 6d61e327fb6..5e2343ad49f 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -475,6 +475,19 @@ public:
     return decl->decl_with_vis.symtab_node;
   }
 
+  /* Worked for the nonstatic set_ifunc_resolver, to vback-propagate
+     ifunc_resolver in the alias chain.  */
+  static bool set_ifunc_resolver (symtab_node *n, void * = NULL)
+  {
+    n->ifunc_resolver = true;
+    return false;
+  }
+
+  /* Set the ifunc_resolver bit in this node and in any aliases thereof.  */
+  void set_ifunc_resolver () {
+    call_for_symbol_and_aliases (set_ifunc_resolver, NULL, true);
+  }
+
   /* Try to find a symtab node for declaration DECL and if it does not
      exist or if it corresponds to an inline clone, create a new one.  */
   static inline symtab_node * get_create (tree node);
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index db6a22a444e..ce13271563f 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -1308,7 +1308,7 @@ input_node (struct lto_file_decl_data *file_data,
       node = symtab->create_empty ();
       node->decl = fn_decl;
       if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl)))
-	node->ifunc_resolver = 1;
+	node->set_ifunc_resolver ();
       node->register_symbol ();
     }
 
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index a2ed048d7dd..26c73d6a1e4 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -160,6 +160,8 @@ create_dispatcher_calls (struct cgraph_node *node)
 	      source->create_reference (inode, IPA_REF_ALIAS);
 	      if (inode->get_comdat_group ())
 		source->add_to_same_comdat_group (inode);
+	      if (!source->ifunc_resolver)
+		source->set_ifunc_resolver ();
 	    }
 	  else
 	    gcc_unreachable ();
diff --git a/gcc/symtab.cc b/gcc/symtab.cc
index 44df52095c1..2101992bfca 100644
--- a/gcc/symtab.cc
+++ b/gcc/symtab.cc
@@ -1125,9 +1125,19 @@ symtab_node::verify_base (void)
           error ("function symbol is not function");
           error_found = true;
 	}
+      /* If the ifunc attribute is present, the node must be marked as
+	 ifunc_resolver, but it may also be marked on a node that
+	 doesn't have the attribute, if it's an alias to another
+	 marked node.  The resolver node itself is an alias to the
+	 function that performs the resolution proper, and that
+	 function is not marked, but here we test other kinds of
+	 aliases, that alias the indirect function.  */
       else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
 		!= NULL)
-	       != dyn_cast <cgraph_node *> (this)->ifunc_resolver)
+	       ? !ifunc_resolver
+	       : ifunc_resolver
+	       ? !get_alias_target ()->ifunc_resolver
+	       : (alias && analyzed && get_alias_target ()->ifunc_resolver))
 	{
 	  error ("inconsistent %<ifunc%> attribute");
           error_found = true;
@@ -1895,6 +1905,9 @@ symtab_node::resolve_alias (symtab_node *target, bool transparent)
   if (target->implicit_section)
     call_for_symbol_and_aliases (set_implicit_section, NULL, true);
 
+  if (target->ifunc_resolver && !ifunc_resolver)
+    set_ifunc_resolver ();
+
   /* Alias targets become redundant after alias is resolved into an reference.
      We do not want to keep it around or we would have to mind updating them
      when renaming symbols.  */
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 167aea87091..7ff4b72e2b4 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -6284,7 +6284,10 @@ do_assemble_alias (tree decl, tree target)
       maybe_assemble_visibility (decl);
     }
   if (TREE_CODE (decl) == FUNCTION_DECL
-      && cgraph_node::get (decl)->ifunc_resolver)
+      && cgraph_node::get (decl)->ifunc_resolver
+      /* Aliases to the ifunc decl will also have the ifunc_resolver
+	 bit set, so check that this is the ifunc declaration.  */
+      && lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
     {
 #if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
       if (targetm.has_ifunc_p ())

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] [PR83782] ifunc: back-propagate ifunc_resolver to aliases
@ 2023-12-14 13:45 Alexandre Oliva
  0 siblings, 0 replies; 13+ messages in thread
From: Alexandre Oliva @ 2023-12-14 13:45 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:c52fd65177a6b64e549ee7e91b89e6295000b4e9

commit c52fd65177a6b64e549ee7e91b89e6295000b4e9
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Thu Dec 14 03:21:28 2023 -0300

    [PR83782] ifunc: back-propagate ifunc_resolver to aliases
    
    gcc.target/i386/mvc10.c fails with -fPIE on ia32 because we omit the
    @PLT mark when calling an alias to an indirect function.  Such aliases
    aren't marked as ifunc_resolvers in the cgraph, so the test that would
    have forced the PLT call fails.
    
    I've arranged for ifunc_resolver to be back-propagated to aliases, and
    relaxed the test that required the ifunc attribute to be attached to
    directly the decl, rather than taken from an aliased decl, when the
    ifunc_resolver bit is set.
    
    
    for  gcc/ChangeLog
    
            PR target/83782
            * cgraph.h (symtab_node::set_ifunc_resolver): New, overloaded.
            Back-propagate flag to aliases.
            * cgraph.cc (cgraph_node::create): Use set_ifunc_resolver.
            (cgraph_node::create_alias): Likewise.
            * lto-cgraph.cc (input_node): Likewise.
            * multiple_target.cc (create_dispatcher_calls): Propagate to
            aliases when redirecting them.
            * symtab.cc (symtab_node::verify_base): Accept ifunc_resolver
            set in an alias to another ifunc_resolver nodes.
            (symtab_node::resolve_alias): Propagate ifunc_resolver from
            resolved target to alias.
            * varasm.cc (do_assemble_alias): Checking for the attribute.

Diff:
---
 gcc/cgraph.cc          |  4 ++--
 gcc/cgraph.h           | 13 +++++++++++++
 gcc/lto-cgraph.cc      |  2 +-
 gcc/multiple_target.cc |  2 ++
 gcc/symtab.cc          | 15 ++++++++++++++-
 gcc/varasm.cc          |  5 ++++-
 6 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 0bef2179e89..cf36d622e20 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -518,7 +518,7 @@ cgraph_node::create (tree decl)
     }
 
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
-    node->ifunc_resolver = true;
+    node->set_ifunc_resolver ();
 
   node->register_symbol ();
   maybe_record_nested_function (node);
@@ -578,7 +578,7 @@ cgraph_node::create_alias (tree alias, tree target)
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     alias_node->transparent_alias = alias_node->weakref = true;
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
-    alias_node->ifunc_resolver = true;
+    alias_node->set_ifunc_resolver ();
   return alias_node;
 }
 
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 6d61e327fb6..5e2343ad49f 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -475,6 +475,19 @@ public:
     return decl->decl_with_vis.symtab_node;
   }
 
+  /* Worked for the nonstatic set_ifunc_resolver, to vback-propagate
+     ifunc_resolver in the alias chain.  */
+  static bool set_ifunc_resolver (symtab_node *n, void * = NULL)
+  {
+    n->ifunc_resolver = true;
+    return false;
+  }
+
+  /* Set the ifunc_resolver bit in this node and in any aliases thereof.  */
+  void set_ifunc_resolver () {
+    call_for_symbol_and_aliases (set_ifunc_resolver, NULL, true);
+  }
+
   /* Try to find a symtab node for declaration DECL and if it does not
      exist or if it corresponds to an inline clone, create a new one.  */
   static inline symtab_node * get_create (tree node);
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index db6a22a444e..ce13271563f 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -1308,7 +1308,7 @@ input_node (struct lto_file_decl_data *file_data,
       node = symtab->create_empty ();
       node->decl = fn_decl;
       if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl)))
-	node->ifunc_resolver = 1;
+	node->set_ifunc_resolver ();
       node->register_symbol ();
     }
 
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index a2ed048d7dd..26c73d6a1e4 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -160,6 +160,8 @@ create_dispatcher_calls (struct cgraph_node *node)
 	      source->create_reference (inode, IPA_REF_ALIAS);
 	      if (inode->get_comdat_group ())
 		source->add_to_same_comdat_group (inode);
+	      if (!source->ifunc_resolver)
+		source->set_ifunc_resolver ();
 	    }
 	  else
 	    gcc_unreachable ();
diff --git a/gcc/symtab.cc b/gcc/symtab.cc
index 44df52095c1..2101992bfca 100644
--- a/gcc/symtab.cc
+++ b/gcc/symtab.cc
@@ -1125,9 +1125,19 @@ symtab_node::verify_base (void)
           error ("function symbol is not function");
           error_found = true;
 	}
+      /* If the ifunc attribute is present, the node must be marked as
+	 ifunc_resolver, but it may also be marked on a node that
+	 doesn't have the attribute, if it's an alias to another
+	 marked node.  The resolver node itself is an alias to the
+	 function that performs the resolution proper, and that
+	 function is not marked, but here we test other kinds of
+	 aliases, that alias the indirect function.  */
       else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
 		!= NULL)
-	       != dyn_cast <cgraph_node *> (this)->ifunc_resolver)
+	       ? !ifunc_resolver
+	       : ifunc_resolver
+	       ? !get_alias_target ()->ifunc_resolver
+	       : (alias && analyzed && get_alias_target ()->ifunc_resolver))
 	{
 	  error ("inconsistent %<ifunc%> attribute");
           error_found = true;
@@ -1895,6 +1905,9 @@ symtab_node::resolve_alias (symtab_node *target, bool transparent)
   if (target->implicit_section)
     call_for_symbol_and_aliases (set_implicit_section, NULL, true);
 
+  if (target->ifunc_resolver && !ifunc_resolver)
+    set_ifunc_resolver ();
+
   /* Alias targets become redundant after alias is resolved into an reference.
      We do not want to keep it around or we would have to mind updating them
      when renaming symbols.  */
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 167aea87091..7ff4b72e2b4 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -6284,7 +6284,10 @@ do_assemble_alias (tree decl, tree target)
       maybe_assemble_visibility (decl);
     }
   if (TREE_CODE (decl) == FUNCTION_DECL
-      && cgraph_node::get (decl)->ifunc_resolver)
+      && cgraph_node::get (decl)->ifunc_resolver
+      /* Aliases to the ifunc decl will also have the ifunc_resolver
+	 bit set, so check that this is the ifunc declaration.  */
+      && lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
     {
 #if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
       if (targetm.has_ifunc_p ())

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] [PR83782] ifunc: back-propagate ifunc_resolver to aliases
@ 2023-12-14 12:48 Alexandre Oliva
  0 siblings, 0 replies; 13+ messages in thread
From: Alexandre Oliva @ 2023-12-14 12:48 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:3c546c83b38b47e9f73f3a1cfcaaddf1c2487e42

commit 3c546c83b38b47e9f73f3a1cfcaaddf1c2487e42
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Thu Dec 14 03:21:28 2023 -0300

    [PR83782] ifunc: back-propagate ifunc_resolver to aliases
    
    gcc.target/i386/mvc10.c fails with -fPIE on ia32 because we omit the
    @PLT mark when calling an alias to an indirect function.  Such aliases
    aren't marked as ifunc_resolvers in the cgraph, so the test that would
    have forced the PLT call fails.
    
    I've arranged for ifunc_resolver to be back-propagated to aliases, and
    relaxed the test that required the ifunc attribute to be attached to
    directly the decl, rather than taken from an aliased decl, when the
    ifunc_resolver bit is set.
    
    
    for  gcc/ChangeLog
    
            PR target/83782
            * cgraph.h (symtab_node::set_ifunc_resolver): New, overloaded.
            Back-propagate flag to aliases.
            * cgraph.cc (cgraph_node::create): Use set_ifunc_resolver.
            (cgraph_node::create_alias): Likewise.
            * lto-cgraph.cc (input_node): Likewise.
            * multiple_target.cc (create_dispatcher_calls): Propagate to
            aliases when redirecting them.
            * symtab.cc (symtab_node::verify_base): Accept ifunc_resolver
            set in an alias to another ifunc_resolver nodes.
            (symtab_node::resolve_alias): Propagate ifunc_resolver from
            resolved target to alias.
            * varasm.cc (do_assemble_alias): Checking for the attribute.

Diff:
---
 gcc/cgraph.cc          |  4 ++--
 gcc/cgraph.h           | 13 +++++++++++++
 gcc/lto-cgraph.cc      |  2 +-
 gcc/multiple_target.cc |  2 ++
 gcc/symtab.cc          | 15 ++++++++++++++-
 gcc/varasm.cc          |  5 ++++-
 6 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 0bef2179e89..cf36d622e20 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -518,7 +518,7 @@ cgraph_node::create (tree decl)
     }
 
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
-    node->ifunc_resolver = true;
+    node->set_ifunc_resolver ();
 
   node->register_symbol ();
   maybe_record_nested_function (node);
@@ -578,7 +578,7 @@ cgraph_node::create_alias (tree alias, tree target)
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     alias_node->transparent_alias = alias_node->weakref = true;
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
-    alias_node->ifunc_resolver = true;
+    alias_node->set_ifunc_resolver ();
   return alias_node;
 }
 
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 6d61e327fb6..5e2343ad49f 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -475,6 +475,19 @@ public:
     return decl->decl_with_vis.symtab_node;
   }
 
+  /* Worked for the nonstatic set_ifunc_resolver, to vback-propagate
+     ifunc_resolver in the alias chain.  */
+  static bool set_ifunc_resolver (symtab_node *n, void * = NULL)
+  {
+    n->ifunc_resolver = true;
+    return false;
+  }
+
+  /* Set the ifunc_resolver bit in this node and in any aliases thereof.  */
+  void set_ifunc_resolver () {
+    call_for_symbol_and_aliases (set_ifunc_resolver, NULL, true);
+  }
+
   /* Try to find a symtab node for declaration DECL and if it does not
      exist or if it corresponds to an inline clone, create a new one.  */
   static inline symtab_node * get_create (tree node);
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index db6a22a444e..ce13271563f 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -1308,7 +1308,7 @@ input_node (struct lto_file_decl_data *file_data,
       node = symtab->create_empty ();
       node->decl = fn_decl;
       if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl)))
-	node->ifunc_resolver = 1;
+	node->set_ifunc_resolver ();
       node->register_symbol ();
     }
 
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index a2ed048d7dd..26c73d6a1e4 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -160,6 +160,8 @@ create_dispatcher_calls (struct cgraph_node *node)
 	      source->create_reference (inode, IPA_REF_ALIAS);
 	      if (inode->get_comdat_group ())
 		source->add_to_same_comdat_group (inode);
+	      if (!source->ifunc_resolver)
+		source->set_ifunc_resolver ();
 	    }
 	  else
 	    gcc_unreachable ();
diff --git a/gcc/symtab.cc b/gcc/symtab.cc
index 44df52095c1..2101992bfca 100644
--- a/gcc/symtab.cc
+++ b/gcc/symtab.cc
@@ -1125,9 +1125,19 @@ symtab_node::verify_base (void)
           error ("function symbol is not function");
           error_found = true;
 	}
+      /* If the ifunc attribute is present, the node must be marked as
+	 ifunc_resolver, but it may also be marked on a node that
+	 doesn't have the attribute, if it's an alias to another
+	 marked node.  The resolver node itself is an alias to the
+	 function that performs the resolution proper, and that
+	 function is not marked, but here we test other kinds of
+	 aliases, that alias the indirect function.  */
       else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
 		!= NULL)
-	       != dyn_cast <cgraph_node *> (this)->ifunc_resolver)
+	       ? !ifunc_resolver
+	       : ifunc_resolver
+	       ? !get_alias_target ()->ifunc_resolver
+	       : (alias && analyzed && get_alias_target ()->ifunc_resolver))
 	{
 	  error ("inconsistent %<ifunc%> attribute");
           error_found = true;
@@ -1895,6 +1905,9 @@ symtab_node::resolve_alias (symtab_node *target, bool transparent)
   if (target->implicit_section)
     call_for_symbol_and_aliases (set_implicit_section, NULL, true);
 
+  if (target->ifunc_resolver && !ifunc_resolver)
+    set_ifunc_resolver ();
+
   /* Alias targets become redundant after alias is resolved into an reference.
      We do not want to keep it around or we would have to mind updating them
      when renaming symbols.  */
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 167aea87091..7ff4b72e2b4 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -6284,7 +6284,10 @@ do_assemble_alias (tree decl, tree target)
       maybe_assemble_visibility (decl);
     }
   if (TREE_CODE (decl) == FUNCTION_DECL
-      && cgraph_node::get (decl)->ifunc_resolver)
+      && cgraph_node::get (decl)->ifunc_resolver
+      /* Aliases to the ifunc decl will also have the ifunc_resolver
+	 bit set, so check that this is the ifunc declaration.  */
+      && lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
     {
 #if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
       if (targetm.has_ifunc_p ())

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] [PR83782] ifunc: back-propagate ifunc_resolver to aliases
@ 2023-12-12 20:23 Alexandre Oliva
  0 siblings, 0 replies; 13+ messages in thread
From: Alexandre Oliva @ 2023-12-12 20:23 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:4dd0bc7b760eec2eca1e6554a726b0580f97a2e6

commit 4dd0bc7b760eec2eca1e6554a726b0580f97a2e6
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Tue Dec 12 00:09:09 2023 -0300

    [PR83782] ifunc: back-propagate ifunc_resolver to aliases
    
    gcc.target/i386/mvc10.c fails with -fPIE on ia32 because we omit the
    @PLT mark when calling an alias to an indirect function.  Such aliases
    aren't marked as ifunc_resolvers in the cgraph, so the test that would
    have forced the PLT call fails.
    
    I've arranged for ifunc_resolver to be back-propagated to aliases, and
    relaxed the test that required the ifunc attribute to be attached to
    directly the decl, rather than taken from an aliased decl, when the
    ifunc_resolver bit is set.
    
    
    for  gcc/ChangeLog
    
            PR target/83782
            * cgraph.h (symtab_node::set_ifunc_resolver): New, overloaded.
            Back-propagate flag to aliases.
            * cgraph.cc (cgraph_node::create): Use set_ifunc_resolver.
            (cgraph_node::create_alias): Likewise.
            * lto-cgraph.cc (input_node): Likewise.
            * multiple_target.cc (create_dispatcher_calls): Propagate to
            aliases when redirecting them.
            * symtab.cc (symtab_node::verify_base): Accept ifunc_resolver
            set in an alias to another ifunc_resolver nodes.
            (symtab_node::resolve_alias): Propagate ifunc_resolver from
            resolved target to alias.
            * varasm.cc (do_assemble_alias): Checking for the attribute.

Diff:
---
 gcc/cgraph.cc          |  4 ++--
 gcc/cgraph.h           | 13 +++++++++++++
 gcc/lto-cgraph.cc      |  2 +-
 gcc/multiple_target.cc |  2 ++
 gcc/symtab.cc          | 15 ++++++++++++++-
 gcc/varasm.cc          |  5 ++++-
 6 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 0bef2179e89..cf36d622e20 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -518,7 +518,7 @@ cgraph_node::create (tree decl)
     }
 
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
-    node->ifunc_resolver = true;
+    node->set_ifunc_resolver ();
 
   node->register_symbol ();
   maybe_record_nested_function (node);
@@ -578,7 +578,7 @@ cgraph_node::create_alias (tree alias, tree target)
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     alias_node->transparent_alias = alias_node->weakref = true;
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
-    alias_node->ifunc_resolver = true;
+    alias_node->set_ifunc_resolver ();
   return alias_node;
 }
 
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 6d61e327fb6..5e2343ad49f 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -475,6 +475,19 @@ public:
     return decl->decl_with_vis.symtab_node;
   }
 
+  /* Worked for the nonstatic set_ifunc_resolver, to vback-propagate
+     ifunc_resolver in the alias chain.  */
+  static bool set_ifunc_resolver (symtab_node *n, void * = NULL)
+  {
+    n->ifunc_resolver = true;
+    return false;
+  }
+
+  /* Set the ifunc_resolver bit in this node and in any aliases thereof.  */
+  void set_ifunc_resolver () {
+    call_for_symbol_and_aliases (set_ifunc_resolver, NULL, true);
+  }
+
   /* Try to find a symtab node for declaration DECL and if it does not
      exist or if it corresponds to an inline clone, create a new one.  */
   static inline symtab_node * get_create (tree node);
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index db6a22a444e..ce13271563f 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -1308,7 +1308,7 @@ input_node (struct lto_file_decl_data *file_data,
       node = symtab->create_empty ();
       node->decl = fn_decl;
       if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl)))
-	node->ifunc_resolver = 1;
+	node->set_ifunc_resolver ();
       node->register_symbol ();
     }
 
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index a2ed048d7dd..26c73d6a1e4 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -160,6 +160,8 @@ create_dispatcher_calls (struct cgraph_node *node)
 	      source->create_reference (inode, IPA_REF_ALIAS);
 	      if (inode->get_comdat_group ())
 		source->add_to_same_comdat_group (inode);
+	      if (!source->ifunc_resolver)
+		source->set_ifunc_resolver ();
 	    }
 	  else
 	    gcc_unreachable ();
diff --git a/gcc/symtab.cc b/gcc/symtab.cc
index 44df52095c1..2101992bfca 100644
--- a/gcc/symtab.cc
+++ b/gcc/symtab.cc
@@ -1125,9 +1125,19 @@ symtab_node::verify_base (void)
           error ("function symbol is not function");
           error_found = true;
 	}
+      /* If the ifunc attribute is present, the node must be marked as
+	 ifunc_resolver, but it may also be marked on a node that
+	 doesn't have the attribute, if it's an alias to another
+	 marked node.  The resolver node itself is an alias to the
+	 function that performs the resolution proper, and that
+	 function is not marked, but here we test other kinds of
+	 aliases, that alias the indirect function.  */
       else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
 		!= NULL)
-	       != dyn_cast <cgraph_node *> (this)->ifunc_resolver)
+	       ? !ifunc_resolver
+	       : ifunc_resolver
+	       ? !get_alias_target ()->ifunc_resolver
+	       : (alias && analyzed && get_alias_target ()->ifunc_resolver))
 	{
 	  error ("inconsistent %<ifunc%> attribute");
           error_found = true;
@@ -1895,6 +1905,9 @@ symtab_node::resolve_alias (symtab_node *target, bool transparent)
   if (target->implicit_section)
     call_for_symbol_and_aliases (set_implicit_section, NULL, true);
 
+  if (target->ifunc_resolver && !ifunc_resolver)
+    set_ifunc_resolver ();
+
   /* Alias targets become redundant after alias is resolved into an reference.
      We do not want to keep it around or we would have to mind updating them
      when renaming symbols.  */
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 167aea87091..7ff4b72e2b4 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -6284,7 +6284,10 @@ do_assemble_alias (tree decl, tree target)
       maybe_assemble_visibility (decl);
     }
   if (TREE_CODE (decl) == FUNCTION_DECL
-      && cgraph_node::get (decl)->ifunc_resolver)
+      && cgraph_node::get (decl)->ifunc_resolver
+      /* Aliases to the ifunc decl will also have the ifunc_resolver
+	 bit set, so check that this is the ifunc declaration.  */
+      && lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
     {
 #if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
       if (targetm.has_ifunc_p ())

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] [PR83782] ifunc: back-propagate ifunc_resolver to aliases
@ 2023-12-12  2:38 Alexandre Oliva
  0 siblings, 0 replies; 13+ messages in thread
From: Alexandre Oliva @ 2023-12-12  2:38 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:684dd0c29a5488b71d3fd36774ec8bf77d97e6a1

commit 684dd0c29a5488b71d3fd36774ec8bf77d97e6a1
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Tue Nov 14 22:15:37 2023 -0300

    [PR83782] ifunc: back-propagate ifunc_resolver to aliases
    
    gcc.target/i386/mvc10.c fails with -fPIE on ia32 because we omit the
    @PLT mark when calling an alias to an indirect function.  Such aliases
    aren't marked as ifunc_resolvers in the cgraph, so the test that would
    have forced the PLT call fails.
    
    I've arranged for ifunc_resolver to be back-propagated to aliases, and
    relaxed the test that required the ifunc attribute to be attached to
    directly the decl, rather than taken from an aliased decl, when the
    ifunc_resolver bit is set.
    
    
    for  gcc/ChangeLog
    
            PR target/83782
            * cgraph.h (symtab_node::set_ifunc_resolver): New, overloaded.
            Back-propagate flag to aliases.
            * cgraph.cc (cgraph_node::create): Use set_ifunc_resolver.
            (cgraph_node::create_alias): Likewise.
            * lto-cgraph.cc (input_node): Likewise.
            * multiple_target.cc (create_dispatcher_calls): Propagate to
            aliases when redirecting them.
            * symtab.cc (symtab_node::verify_base): Accept ifunc_resolver
            set in an alias to another ifunc_resolver nodes.
            (symtab_node::resolve_alias): Propagate ifunc_resolver from
            resolved target to alias.
            * varasm.cc (do_assemble_alias): Checking for the attribute.

Diff:
---
 gcc/cgraph.cc          |  4 ++--
 gcc/cgraph.h           | 13 +++++++++++++
 gcc/lto-cgraph.cc      |  2 +-
 gcc/multiple_target.cc |  2 ++
 gcc/symtab.cc          | 15 ++++++++++++++-
 gcc/varasm.cc          |  5 ++++-
 6 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 0bef2179e89..cf36d622e20 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -518,7 +518,7 @@ cgraph_node::create (tree decl)
     }
 
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
-    node->ifunc_resolver = true;
+    node->set_ifunc_resolver ();
 
   node->register_symbol ();
   maybe_record_nested_function (node);
@@ -578,7 +578,7 @@ cgraph_node::create_alias (tree alias, tree target)
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     alias_node->transparent_alias = alias_node->weakref = true;
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
-    alias_node->ifunc_resolver = true;
+    alias_node->set_ifunc_resolver ();
   return alias_node;
 }
 
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 6d61e327fb6..5e2343ad49f 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -475,6 +475,19 @@ public:
     return decl->decl_with_vis.symtab_node;
   }
 
+  /* Worked for the nonstatic set_ifunc_resolver, to vback-propagate
+     ifunc_resolver in the alias chain.  */
+  static bool set_ifunc_resolver (symtab_node *n, void * = NULL)
+  {
+    n->ifunc_resolver = true;
+    return false;
+  }
+
+  /* Set the ifunc_resolver bit in this node and in any aliases thereof.  */
+  void set_ifunc_resolver () {
+    call_for_symbol_and_aliases (set_ifunc_resolver, NULL, true);
+  }
+
   /* Try to find a symtab node for declaration DECL and if it does not
      exist or if it corresponds to an inline clone, create a new one.  */
   static inline symtab_node * get_create (tree node);
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index db6a22a444e..ce13271563f 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -1308,7 +1308,7 @@ input_node (struct lto_file_decl_data *file_data,
       node = symtab->create_empty ();
       node->decl = fn_decl;
       if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl)))
-	node->ifunc_resolver = 1;
+	node->set_ifunc_resolver ();
       node->register_symbol ();
     }
 
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index a2ed048d7dd..26c73d6a1e4 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -160,6 +160,8 @@ create_dispatcher_calls (struct cgraph_node *node)
 	      source->create_reference (inode, IPA_REF_ALIAS);
 	      if (inode->get_comdat_group ())
 		source->add_to_same_comdat_group (inode);
+	      if (!source->ifunc_resolver)
+		source->set_ifunc_resolver ();
 	    }
 	  else
 	    gcc_unreachable ();
diff --git a/gcc/symtab.cc b/gcc/symtab.cc
index 44df52095c1..2101992bfca 100644
--- a/gcc/symtab.cc
+++ b/gcc/symtab.cc
@@ -1125,9 +1125,19 @@ symtab_node::verify_base (void)
           error ("function symbol is not function");
           error_found = true;
 	}
+      /* If the ifunc attribute is present, the node must be marked as
+	 ifunc_resolver, but it may also be marked on a node that
+	 doesn't have the attribute, if it's an alias to another
+	 marked node.  The resolver node itself is an alias to the
+	 function that performs the resolution proper, and that
+	 function is not marked, but here we test other kinds of
+	 aliases, that alias the indirect function.  */
       else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
 		!= NULL)
-	       != dyn_cast <cgraph_node *> (this)->ifunc_resolver)
+	       ? !ifunc_resolver
+	       : ifunc_resolver
+	       ? !get_alias_target ()->ifunc_resolver
+	       : (alias && analyzed && get_alias_target ()->ifunc_resolver))
 	{
 	  error ("inconsistent %<ifunc%> attribute");
           error_found = true;
@@ -1895,6 +1905,9 @@ symtab_node::resolve_alias (symtab_node *target, bool transparent)
   if (target->implicit_section)
     call_for_symbol_and_aliases (set_implicit_section, NULL, true);
 
+  if (target->ifunc_resolver && !ifunc_resolver)
+    set_ifunc_resolver ();
+
   /* Alias targets become redundant after alias is resolved into an reference.
      We do not want to keep it around or we would have to mind updating them
      when renaming symbols.  */
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 167aea87091..7ff4b72e2b4 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -6284,7 +6284,10 @@ do_assemble_alias (tree decl, tree target)
       maybe_assemble_visibility (decl);
     }
   if (TREE_CODE (decl) == FUNCTION_DECL
-      && cgraph_node::get (decl)->ifunc_resolver)
+      && cgraph_node::get (decl)->ifunc_resolver
+      /* Aliases to the ifunc decl will also have the ifunc_resolver
+	 bit set, so check that this is the ifunc declaration.  */
+      && lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
     {
 #if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
       if (targetm.has_ifunc_p ())

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] [PR83782] ifunc: back-propagate ifunc_resolver to aliases
@ 2023-11-09  1:58 Alexandre Oliva
  0 siblings, 0 replies; 13+ messages in thread
From: Alexandre Oliva @ 2023-11-09  1:58 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:1e96d7b7b6a9abd07b210c4a2d1fc9ae5f9558aa

commit 1e96d7b7b6a9abd07b210c4a2d1fc9ae5f9558aa
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Mon Aug 8 16:34:18 2022 -0300

    [PR83782] ifunc: back-propagate ifunc_resolver to aliases
    
    gcc.target/i386/mvc10.c fails with -fPIE on ia32 because we omit the
    @PLT mark when calling an alias to an indirect function.  Such aliases
    aren't marked as ifunc_resolvers in the cgraph, so the test that would
    have forced the PLT call fails.
    
    I've arranged for ifunc_resolver to be back-propagated to aliases, and
    relaxed the test that required the ifunc attribute to be attached to
    directly the decl, rather than taken from an aliased decl, when the
    ifunc_resolver bit is set.
    
    
    for  gcc/ChangeLog
    
            PR target/83782
            * cgraph.h (symtab_node::set_ifunc_resolver): New, overloaded.
            Back-propagate flag to aliases.
            * cgraph.cc (cgraph_node::create): Use set_ifunc_resolver.
            (cgraph_node::create_alias): Likewise.
            * lto-cgraph.cc (input_node): Likewise.
            * multiple_target.cc (create_dispatcher_calls): Propagate to
            aliases when redirecting them.
            * symtab.cc (symtab_node::verify_base): Accept ifunc_resolver
            set in an alias to another ifunc_resolver nodes.
            (symtab_node::resolve_alias): Propagate ifunc_resolver from
            resolved target to alias.
            * varasm.cc (do_assemble_alias): Checking for the attribute.

Diff:
---
 gcc/cgraph.cc          |  4 ++--
 gcc/cgraph.h           | 13 +++++++++++++
 gcc/lto-cgraph.cc      |  2 +-
 gcc/multiple_target.cc |  2 ++
 gcc/symtab.cc          | 15 ++++++++++++++-
 gcc/varasm.cc          |  5 ++++-
 6 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index e41e5ad3ae7..046dadf53af 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -518,7 +518,7 @@ cgraph_node::create (tree decl)
     }
 
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
-    node->ifunc_resolver = true;
+    node->set_ifunc_resolver ();
 
   node->register_symbol ();
   maybe_record_nested_function (node);
@@ -576,7 +576,7 @@ cgraph_node::create_alias (tree alias, tree target)
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     alias_node->transparent_alias = alias_node->weakref = true;
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
-    alias_node->ifunc_resolver = true;
+    alias_node->set_ifunc_resolver ();
   return alias_node;
 }
 
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index cedaaac3a45..e118ac75121 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -471,6 +471,19 @@ public:
     return decl->decl_with_vis.symtab_node;
   }
 
+  /* Worked for the nonstatic set_ifunc_resolver, to vback-propagate
+     ifunc_resolver in the alias chain.  */
+  static bool set_ifunc_resolver (symtab_node *n, void * = NULL)
+  {
+    n->ifunc_resolver = true;
+    return false;
+  }
+
+  /* Set the ifunc_resolver bit in this node and in any aliases thereof.  */
+  void set_ifunc_resolver () {
+    call_for_symbol_and_aliases (set_ifunc_resolver, NULL, true);
+  }
+
   /* Try to find a symtab node for declaration DECL and if it does not
      exist or if it corresponds to an inline clone, create a new one.  */
   static inline symtab_node * get_create (tree node);
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index 32c0f5ac6db..e7f77ca7224 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -1294,7 +1294,7 @@ input_node (struct lto_file_decl_data *file_data,
       node = symtab->create_empty ();
       node->decl = fn_decl;
       if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl)))
-	node->ifunc_resolver = 1;
+	node->set_ifunc_resolver ();
       node->register_symbol ();
     }
 
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index a2ed048d7dd..26c73d6a1e4 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -160,6 +160,8 @@ create_dispatcher_calls (struct cgraph_node *node)
 	      source->create_reference (inode, IPA_REF_ALIAS);
 	      if (inode->get_comdat_group ())
 		source->add_to_same_comdat_group (inode);
+	      if (!source->ifunc_resolver)
+		source->set_ifunc_resolver ();
 	    }
 	  else
 	    gcc_unreachable ();
diff --git a/gcc/symtab.cc b/gcc/symtab.cc
index 0470509a98d..b35b879028d 100644
--- a/gcc/symtab.cc
+++ b/gcc/symtab.cc
@@ -1109,9 +1109,19 @@ symtab_node::verify_base (void)
           error ("function symbol is not function");
           error_found = true;
 	}
+      /* If the ifunc attribute is present, the node must be marked as
+	 ifunc_resolver, but it may also be marked on a node that
+	 doesn't have the attribute, if it's an alias to another
+	 marked node.  The resolver node itself is an alias to the
+	 function that performs the resolution proper, and that
+	 function is not marked, but here we test other kinds of
+	 aliases, that alias the indirect function.  */
       else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
 		!= NULL)
-	       != dyn_cast <cgraph_node *> (this)->ifunc_resolver)
+	       ? !ifunc_resolver
+	       : ifunc_resolver
+	       ? !get_alias_target ()->ifunc_resolver
+	       : (alias && analyzed && get_alias_target ()->ifunc_resolver))
 	{
 	  error ("inconsistent %<ifunc%> attribute");
           error_found = true;
@@ -1879,6 +1889,9 @@ symtab_node::resolve_alias (symtab_node *target, bool transparent)
   if (target->implicit_section)
     call_for_symbol_and_aliases (set_implicit_section, NULL, true);
 
+  if (target->ifunc_resolver && !ifunc_resolver)
+    set_ifunc_resolver ();
+
   /* Alias targets become redundant after alias is resolved into an reference.
      We do not want to keep it around or we would have to mind updating them
      when renaming symbols.  */
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 6ae35edc5ae..c6aa7c1745d 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -6262,7 +6262,10 @@ do_assemble_alias (tree decl, tree target)
       maybe_assemble_visibility (decl);
     }
   if (TREE_CODE (decl) == FUNCTION_DECL
-      && cgraph_node::get (decl)->ifunc_resolver)
+      && cgraph_node::get (decl)->ifunc_resolver
+      /* Aliases to the ifunc decl will also have the ifunc_resolver
+	 bit set, so check that this is the ifunc declaration.  */
+      && lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
     {
 #if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
       if (targetm.has_ifunc_p ())

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] [PR83782] ifunc: back-propagate ifunc_resolver to aliases
@ 2023-11-08 23:48 Alexandre Oliva
  0 siblings, 0 replies; 13+ messages in thread
From: Alexandre Oliva @ 2023-11-08 23:48 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:b96dfca13f48049a1fa9ab67a1313ee9df91e8b5

commit b96dfca13f48049a1fa9ab67a1313ee9df91e8b5
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Mon Aug 8 16:34:18 2022 -0300

    [PR83782] ifunc: back-propagate ifunc_resolver to aliases
    
    gcc.target/i386/mvc10.c fails with -fPIE on ia32 because we omit the
    @PLT mark when calling an alias to an indirect function.  Such aliases
    aren't marked as ifunc_resolvers in the cgraph, so the test that would
    have forced the PLT call fails.
    
    I've arranged for ifunc_resolver to be back-propagated to aliases, and
    relaxed the test that required the ifunc attribute to be attached to
    directly the decl, rather than taken from an aliased decl, when the
    ifunc_resolver bit is set.
    
    
    for  gcc/ChangeLog
    
            PR target/83782
            * cgraph.h (symtab_node::set_ifunc_resolver): New, overloaded.
            Back-propagate flag to aliases.
            * cgraph.cc (cgraph_node::create): Use set_ifunc_resolver.
            (cgraph_node::create_alias): Likewise.
            * lto-cgraph.cc (input_node): Likewise.
            * multiple_target.cc (create_dispatcher_calls): Propagate to
            aliases when redirecting them.
            * symtab.cc (symtab_node::verify_base): Accept ifunc_resolver
            set in an alias to another ifunc_resolver nodes.
            (symtab_node::resolve_alias): Propagate ifunc_resolver from
            resolved target to alias.
            * varasm.cc (do_assemble_alias): Checking for the attribute.

Diff:
---
 gcc/cgraph.cc          |  4 ++--
 gcc/cgraph.h           | 13 +++++++++++++
 gcc/lto-cgraph.cc      |  2 +-
 gcc/multiple_target.cc |  2 ++
 gcc/symtab.cc          | 15 ++++++++++++++-
 gcc/varasm.cc          |  5 ++++-
 6 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index e41e5ad3ae7..046dadf53af 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -518,7 +518,7 @@ cgraph_node::create (tree decl)
     }
 
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
-    node->ifunc_resolver = true;
+    node->set_ifunc_resolver ();
 
   node->register_symbol ();
   maybe_record_nested_function (node);
@@ -576,7 +576,7 @@ cgraph_node::create_alias (tree alias, tree target)
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     alias_node->transparent_alias = alias_node->weakref = true;
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
-    alias_node->ifunc_resolver = true;
+    alias_node->set_ifunc_resolver ();
   return alias_node;
 }
 
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index cedaaac3a45..e118ac75121 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -471,6 +471,19 @@ public:
     return decl->decl_with_vis.symtab_node;
   }
 
+  /* Worked for the nonstatic set_ifunc_resolver, to vback-propagate
+     ifunc_resolver in the alias chain.  */
+  static bool set_ifunc_resolver (symtab_node *n, void * = NULL)
+  {
+    n->ifunc_resolver = true;
+    return false;
+  }
+
+  /* Set the ifunc_resolver bit in this node and in any aliases thereof.  */
+  void set_ifunc_resolver () {
+    call_for_symbol_and_aliases (set_ifunc_resolver, NULL, true);
+  }
+
   /* Try to find a symtab node for declaration DECL and if it does not
      exist or if it corresponds to an inline clone, create a new one.  */
   static inline symtab_node * get_create (tree node);
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index 32c0f5ac6db..e7f77ca7224 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -1294,7 +1294,7 @@ input_node (struct lto_file_decl_data *file_data,
       node = symtab->create_empty ();
       node->decl = fn_decl;
       if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl)))
-	node->ifunc_resolver = 1;
+	node->set_ifunc_resolver ();
       node->register_symbol ();
     }
 
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index a2ed048d7dd..26c73d6a1e4 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -160,6 +160,8 @@ create_dispatcher_calls (struct cgraph_node *node)
 	      source->create_reference (inode, IPA_REF_ALIAS);
 	      if (inode->get_comdat_group ())
 		source->add_to_same_comdat_group (inode);
+	      if (!source->ifunc_resolver)
+		source->set_ifunc_resolver ();
 	    }
 	  else
 	    gcc_unreachable ();
diff --git a/gcc/symtab.cc b/gcc/symtab.cc
index 0470509a98d..b35b879028d 100644
--- a/gcc/symtab.cc
+++ b/gcc/symtab.cc
@@ -1109,9 +1109,19 @@ symtab_node::verify_base (void)
           error ("function symbol is not function");
           error_found = true;
 	}
+      /* If the ifunc attribute is present, the node must be marked as
+	 ifunc_resolver, but it may also be marked on a node that
+	 doesn't have the attribute, if it's an alias to another
+	 marked node.  The resolver node itself is an alias to the
+	 function that performs the resolution proper, and that
+	 function is not marked, but here we test other kinds of
+	 aliases, that alias the indirect function.  */
       else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
 		!= NULL)
-	       != dyn_cast <cgraph_node *> (this)->ifunc_resolver)
+	       ? !ifunc_resolver
+	       : ifunc_resolver
+	       ? !get_alias_target ()->ifunc_resolver
+	       : (alias && analyzed && get_alias_target ()->ifunc_resolver))
 	{
 	  error ("inconsistent %<ifunc%> attribute");
           error_found = true;
@@ -1879,6 +1889,9 @@ symtab_node::resolve_alias (symtab_node *target, bool transparent)
   if (target->implicit_section)
     call_for_symbol_and_aliases (set_implicit_section, NULL, true);
 
+  if (target->ifunc_resolver && !ifunc_resolver)
+    set_ifunc_resolver ();
+
   /* Alias targets become redundant after alias is resolved into an reference.
      We do not want to keep it around or we would have to mind updating them
      when renaming symbols.  */
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 6ae35edc5ae..c6aa7c1745d 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -6262,7 +6262,10 @@ do_assemble_alias (tree decl, tree target)
       maybe_assemble_visibility (decl);
     }
   if (TREE_CODE (decl) == FUNCTION_DECL
-      && cgraph_node::get (decl)->ifunc_resolver)
+      && cgraph_node::get (decl)->ifunc_resolver
+      /* Aliases to the ifunc decl will also have the ifunc_resolver
+	 bit set, so check that this is the ifunc declaration.  */
+      && lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
     {
 #if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
       if (targetm.has_ifunc_p ())

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] [PR83782] ifunc: back-propagate ifunc_resolver to aliases
@ 2023-11-08 19:22 Alexandre Oliva
  0 siblings, 0 replies; 13+ messages in thread
From: Alexandre Oliva @ 2023-11-08 19:22 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:21792c476fb8b7e5ae6a9844ffcfc9280792f799

commit 21792c476fb8b7e5ae6a9844ffcfc9280792f799
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Mon Aug 8 16:34:18 2022 -0300

    [PR83782] ifunc: back-propagate ifunc_resolver to aliases
    
    gcc.target/i386/mvc10.c fails with -fPIE on ia32 because we omit the
    @PLT mark when calling an alias to an indirect function.  Such aliases
    aren't marked as ifunc_resolvers in the cgraph, so the test that would
    have forced the PLT call fails.
    
    I've arranged for ifunc_resolver to be back-propagated to aliases, and
    relaxed the test that required the ifunc attribute to be attached to
    directly the decl, rather than taken from an aliased decl, when the
    ifunc_resolver bit is set.
    
    
    for  gcc/ChangeLog
    
            PR target/83782
            * cgraph.h (symtab_node::set_ifunc_resolver): New, overloaded.
            Back-propagate flag to aliases.
            * cgraph.cc (cgraph_node::create): Use set_ifunc_resolver.
            (cgraph_node::create_alias): Likewise.
            * lto-cgraph.cc (input_node): Likewise.
            * multiple_target.cc (create_dispatcher_calls): Propagate to
            aliases when redirecting them.
            * symtab.cc (symtab_node::verify_base): Accept ifunc_resolver
            set in an alias to another ifunc_resolver nodes.
            (symtab_node::resolve_alias): Propagate ifunc_resolver from
            resolved target to alias.
            * varasm.cc (do_assemble_alias): Checking for the attribute.

Diff:
---
 gcc/cgraph.cc          |  4 ++--
 gcc/cgraph.h           | 13 +++++++++++++
 gcc/lto-cgraph.cc      |  2 +-
 gcc/multiple_target.cc |  2 ++
 gcc/symtab.cc          | 15 ++++++++++++++-
 gcc/varasm.cc          |  5 ++++-
 6 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index e41e5ad3ae7..046dadf53af 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -518,7 +518,7 @@ cgraph_node::create (tree decl)
     }
 
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
-    node->ifunc_resolver = true;
+    node->set_ifunc_resolver ();
 
   node->register_symbol ();
   maybe_record_nested_function (node);
@@ -576,7 +576,7 @@ cgraph_node::create_alias (tree alias, tree target)
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     alias_node->transparent_alias = alias_node->weakref = true;
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
-    alias_node->ifunc_resolver = true;
+    alias_node->set_ifunc_resolver ();
   return alias_node;
 }
 
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index cedaaac3a45..e118ac75121 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -471,6 +471,19 @@ public:
     return decl->decl_with_vis.symtab_node;
   }
 
+  /* Worked for the nonstatic set_ifunc_resolver, to vback-propagate
+     ifunc_resolver in the alias chain.  */
+  static bool set_ifunc_resolver (symtab_node *n, void * = NULL)
+  {
+    n->ifunc_resolver = true;
+    return false;
+  }
+
+  /* Set the ifunc_resolver bit in this node and in any aliases thereof.  */
+  void set_ifunc_resolver () {
+    call_for_symbol_and_aliases (set_ifunc_resolver, NULL, true);
+  }
+
   /* Try to find a symtab node for declaration DECL and if it does not
      exist or if it corresponds to an inline clone, create a new one.  */
   static inline symtab_node * get_create (tree node);
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index 32c0f5ac6db..e7f77ca7224 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -1294,7 +1294,7 @@ input_node (struct lto_file_decl_data *file_data,
       node = symtab->create_empty ();
       node->decl = fn_decl;
       if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl)))
-	node->ifunc_resolver = 1;
+	node->set_ifunc_resolver ();
       node->register_symbol ();
     }
 
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index a2ed048d7dd..26c73d6a1e4 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -160,6 +160,8 @@ create_dispatcher_calls (struct cgraph_node *node)
 	      source->create_reference (inode, IPA_REF_ALIAS);
 	      if (inode->get_comdat_group ())
 		source->add_to_same_comdat_group (inode);
+	      if (!source->ifunc_resolver)
+		source->set_ifunc_resolver ();
 	    }
 	  else
 	    gcc_unreachable ();
diff --git a/gcc/symtab.cc b/gcc/symtab.cc
index 0470509a98d..b35b879028d 100644
--- a/gcc/symtab.cc
+++ b/gcc/symtab.cc
@@ -1109,9 +1109,19 @@ symtab_node::verify_base (void)
           error ("function symbol is not function");
           error_found = true;
 	}
+      /* If the ifunc attribute is present, the node must be marked as
+	 ifunc_resolver, but it may also be marked on a node that
+	 doesn't have the attribute, if it's an alias to another
+	 marked node.  The resolver node itself is an alias to the
+	 function that performs the resolution proper, and that
+	 function is not marked, but here we test other kinds of
+	 aliases, that alias the indirect function.  */
       else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
 		!= NULL)
-	       != dyn_cast <cgraph_node *> (this)->ifunc_resolver)
+	       ? !ifunc_resolver
+	       : ifunc_resolver
+	       ? !get_alias_target ()->ifunc_resolver
+	       : (alias && analyzed && get_alias_target ()->ifunc_resolver))
 	{
 	  error ("inconsistent %<ifunc%> attribute");
           error_found = true;
@@ -1879,6 +1889,9 @@ symtab_node::resolve_alias (symtab_node *target, bool transparent)
   if (target->implicit_section)
     call_for_symbol_and_aliases (set_implicit_section, NULL, true);
 
+  if (target->ifunc_resolver && !ifunc_resolver)
+    set_ifunc_resolver ();
+
   /* Alias targets become redundant after alias is resolved into an reference.
      We do not want to keep it around or we would have to mind updating them
      when renaming symbols.  */
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 6ae35edc5ae..c6aa7c1745d 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -6262,7 +6262,10 @@ do_assemble_alias (tree decl, tree target)
       maybe_assemble_visibility (decl);
     }
   if (TREE_CODE (decl) == FUNCTION_DECL
-      && cgraph_node::get (decl)->ifunc_resolver)
+      && cgraph_node::get (decl)->ifunc_resolver
+      /* Aliases to the ifunc decl will also have the ifunc_resolver
+	 bit set, so check that this is the ifunc declaration.  */
+      && lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
     {
 #if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
       if (targetm.has_ifunc_p ())

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] [PR83782] ifunc: back-propagate ifunc_resolver to aliases
@ 2023-11-07 11:33 Alexandre Oliva
  0 siblings, 0 replies; 13+ messages in thread
From: Alexandre Oliva @ 2023-11-07 11:33 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:1be74541d99e8b56912e069d07df16f589a0738d

commit 1be74541d99e8b56912e069d07df16f589a0738d
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Mon Aug 8 16:34:18 2022 -0300

    [PR83782] ifunc: back-propagate ifunc_resolver to aliases
    
    gcc.target/i386/mvc10.c fails with -fPIE on ia32 because we omit the
    @PLT mark when calling an alias to an indirect function.  Such aliases
    aren't marked as ifunc_resolvers in the cgraph, so the test that would
    have forced the PLT call fails.
    
    I've arranged for ifunc_resolver to be back-propagated to aliases, and
    relaxed the test that required the ifunc attribute to be attached to
    directly the decl, rather than taken from an aliased decl, when the
    ifunc_resolver bit is set.
    
    
    for  gcc/ChangeLog
    
            PR target/83782
            * cgraph.h (symtab_node::set_ifunc_resolver): New, overloaded.
            Back-propagate flag to aliases.
            * cgraph.cc (cgraph_node::create): Use set_ifunc_resolver.
            (cgraph_node::create_alias): Likewise.
            * lto-cgraph.cc (input_node): Likewise.
            * multiple_target.cc (create_dispatcher_calls): Propagate to
            aliases when redirecting them.
            * symtab.cc (symtab_node::verify_base): Accept ifunc_resolver
            set in an alias to another ifunc_resolver nodes.
            (symtab_node::resolve_alias): Propagate ifunc_resolver from
            resolved target to alias.
            * varasm.cc (do_assemble_alias): Checking for the attribute.

Diff:
---
 gcc/cgraph.cc          |  4 ++--
 gcc/cgraph.h           | 13 +++++++++++++
 gcc/lto-cgraph.cc      |  2 +-
 gcc/multiple_target.cc |  2 ++
 gcc/symtab.cc          | 15 ++++++++++++++-
 gcc/varasm.cc          |  5 ++++-
 6 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index e41e5ad3ae7..046dadf53af 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -518,7 +518,7 @@ cgraph_node::create (tree decl)
     }
 
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
-    node->ifunc_resolver = true;
+    node->set_ifunc_resolver ();
 
   node->register_symbol ();
   maybe_record_nested_function (node);
@@ -576,7 +576,7 @@ cgraph_node::create_alias (tree alias, tree target)
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     alias_node->transparent_alias = alias_node->weakref = true;
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
-    alias_node->ifunc_resolver = true;
+    alias_node->set_ifunc_resolver ();
   return alias_node;
 }
 
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index cedaaac3a45..e118ac75121 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -471,6 +471,19 @@ public:
     return decl->decl_with_vis.symtab_node;
   }
 
+  /* Worked for the nonstatic set_ifunc_resolver, to vback-propagate
+     ifunc_resolver in the alias chain.  */
+  static bool set_ifunc_resolver (symtab_node *n, void * = NULL)
+  {
+    n->ifunc_resolver = true;
+    return false;
+  }
+
+  /* Set the ifunc_resolver bit in this node and in any aliases thereof.  */
+  void set_ifunc_resolver () {
+    call_for_symbol_and_aliases (set_ifunc_resolver, NULL, true);
+  }
+
   /* Try to find a symtab node for declaration DECL and if it does not
      exist or if it corresponds to an inline clone, create a new one.  */
   static inline symtab_node * get_create (tree node);
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index 32c0f5ac6db..e7f77ca7224 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -1294,7 +1294,7 @@ input_node (struct lto_file_decl_data *file_data,
       node = symtab->create_empty ();
       node->decl = fn_decl;
       if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl)))
-	node->ifunc_resolver = 1;
+	node->set_ifunc_resolver ();
       node->register_symbol ();
     }
 
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index a2ed048d7dd..26c73d6a1e4 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -160,6 +160,8 @@ create_dispatcher_calls (struct cgraph_node *node)
 	      source->create_reference (inode, IPA_REF_ALIAS);
 	      if (inode->get_comdat_group ())
 		source->add_to_same_comdat_group (inode);
+	      if (!source->ifunc_resolver)
+		source->set_ifunc_resolver ();
 	    }
 	  else
 	    gcc_unreachable ();
diff --git a/gcc/symtab.cc b/gcc/symtab.cc
index 0470509a98d..b35b879028d 100644
--- a/gcc/symtab.cc
+++ b/gcc/symtab.cc
@@ -1109,9 +1109,19 @@ symtab_node::verify_base (void)
           error ("function symbol is not function");
           error_found = true;
 	}
+      /* If the ifunc attribute is present, the node must be marked as
+	 ifunc_resolver, but it may also be marked on a node that
+	 doesn't have the attribute, if it's an alias to another
+	 marked node.  The resolver node itself is an alias to the
+	 function that performs the resolution proper, and that
+	 function is not marked, but here we test other kinds of
+	 aliases, that alias the indirect function.  */
       else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
 		!= NULL)
-	       != dyn_cast <cgraph_node *> (this)->ifunc_resolver)
+	       ? !ifunc_resolver
+	       : ifunc_resolver
+	       ? !get_alias_target ()->ifunc_resolver
+	       : (alias && analyzed && get_alias_target ()->ifunc_resolver))
 	{
 	  error ("inconsistent %<ifunc%> attribute");
           error_found = true;
@@ -1879,6 +1889,9 @@ symtab_node::resolve_alias (symtab_node *target, bool transparent)
   if (target->implicit_section)
     call_for_symbol_and_aliases (set_implicit_section, NULL, true);
 
+  if (target->ifunc_resolver && !ifunc_resolver)
+    set_ifunc_resolver ();
+
   /* Alias targets become redundant after alias is resolved into an reference.
      We do not want to keep it around or we would have to mind updating them
      when renaming symbols.  */
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 6ae35edc5ae..c6aa7c1745d 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -6262,7 +6262,10 @@ do_assemble_alias (tree decl, tree target)
       maybe_assemble_visibility (decl);
     }
   if (TREE_CODE (decl) == FUNCTION_DECL
-      && cgraph_node::get (decl)->ifunc_resolver)
+      && cgraph_node::get (decl)->ifunc_resolver
+      /* Aliases to the ifunc decl will also have the ifunc_resolver
+	 bit set, so check that this is the ifunc declaration.  */
+      && lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
     {
 #if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
       if (targetm.has_ifunc_p ())

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] [PR83782] ifunc: back-propagate ifunc_resolver to aliases
@ 2023-11-06 18:06 Alexandre Oliva
  0 siblings, 0 replies; 13+ messages in thread
From: Alexandre Oliva @ 2023-11-06 18:06 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:5ff7df27de2db14fcf56c8bf570f44944d1dd030

commit 5ff7df27de2db14fcf56c8bf570f44944d1dd030
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Mon Aug 8 16:34:18 2022 -0300

    [PR83782] ifunc: back-propagate ifunc_resolver to aliases
    
    gcc.target/i386/mvc10.c fails with -fPIE on ia32 because we omit the
    @PLT mark when calling an alias to an indirect function.  Such aliases
    aren't marked as ifunc_resolvers in the cgraph, so the test that would
    have forced the PLT call fails.
    
    I've arranged for ifunc_resolver to be back-propagated to aliases, and
    relaxed the test that required the ifunc attribute to be attached to
    directly the decl, rather than taken from an aliased decl, when the
    ifunc_resolver bit is set.
    
    
    for  gcc/ChangeLog
    
            PR target/83782
            * cgraph.h (symtab_node::set_ifunc_resolver): New, overloaded.
            Back-propagate flag to aliases.
            * cgraph.cc (cgraph_node::create): Use set_ifunc_resolver.
            (cgraph_node::create_alias): Likewise.
            * lto-cgraph.cc (input_node): Likewise.
            * multiple_target.cc (create_dispatcher_calls): Propagate to
            aliases when redirecting them.
            * symtab.cc (symtab_node::verify_base): Accept ifunc_resolver
            set in an alias to another ifunc_resolver nodes.
            (symtab_node::resolve_alias): Propagate ifunc_resolver from
            resolved target to alias.
            * varasm.cc (do_assemble_alias): Checking for the attribute.

Diff:
---
 gcc/cgraph.cc          |  4 ++--
 gcc/cgraph.h           | 13 +++++++++++++
 gcc/lto-cgraph.cc      |  2 +-
 gcc/multiple_target.cc |  2 ++
 gcc/symtab.cc          | 15 ++++++++++++++-
 gcc/varasm.cc          |  5 ++++-
 6 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index e41e5ad3ae7..046dadf53af 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -518,7 +518,7 @@ cgraph_node::create (tree decl)
     }
 
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
-    node->ifunc_resolver = true;
+    node->set_ifunc_resolver ();
 
   node->register_symbol ();
   maybe_record_nested_function (node);
@@ -576,7 +576,7 @@ cgraph_node::create_alias (tree alias, tree target)
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     alias_node->transparent_alias = alias_node->weakref = true;
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
-    alias_node->ifunc_resolver = true;
+    alias_node->set_ifunc_resolver ();
   return alias_node;
 }
 
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index cedaaac3a45..e118ac75121 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -471,6 +471,19 @@ public:
     return decl->decl_with_vis.symtab_node;
   }
 
+  /* Worked for the nonstatic set_ifunc_resolver, to vback-propagate
+     ifunc_resolver in the alias chain.  */
+  static bool set_ifunc_resolver (symtab_node *n, void * = NULL)
+  {
+    n->ifunc_resolver = true;
+    return false;
+  }
+
+  /* Set the ifunc_resolver bit in this node and in any aliases thereof.  */
+  void set_ifunc_resolver () {
+    call_for_symbol_and_aliases (set_ifunc_resolver, NULL, true);
+  }
+
   /* Try to find a symtab node for declaration DECL and if it does not
      exist or if it corresponds to an inline clone, create a new one.  */
   static inline symtab_node * get_create (tree node);
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index 32c0f5ac6db..e7f77ca7224 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -1294,7 +1294,7 @@ input_node (struct lto_file_decl_data *file_data,
       node = symtab->create_empty ();
       node->decl = fn_decl;
       if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl)))
-	node->ifunc_resolver = 1;
+	node->set_ifunc_resolver ();
       node->register_symbol ();
     }
 
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index a2ed048d7dd..26c73d6a1e4 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -160,6 +160,8 @@ create_dispatcher_calls (struct cgraph_node *node)
 	      source->create_reference (inode, IPA_REF_ALIAS);
 	      if (inode->get_comdat_group ())
 		source->add_to_same_comdat_group (inode);
+	      if (!source->ifunc_resolver)
+		source->set_ifunc_resolver ();
 	    }
 	  else
 	    gcc_unreachable ();
diff --git a/gcc/symtab.cc b/gcc/symtab.cc
index 0470509a98d..b35b879028d 100644
--- a/gcc/symtab.cc
+++ b/gcc/symtab.cc
@@ -1109,9 +1109,19 @@ symtab_node::verify_base (void)
           error ("function symbol is not function");
           error_found = true;
 	}
+      /* If the ifunc attribute is present, the node must be marked as
+	 ifunc_resolver, but it may also be marked on a node that
+	 doesn't have the attribute, if it's an alias to another
+	 marked node.  The resolver node itself is an alias to the
+	 function that performs the resolution proper, and that
+	 function is not marked, but here we test other kinds of
+	 aliases, that alias the indirect function.  */
       else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
 		!= NULL)
-	       != dyn_cast <cgraph_node *> (this)->ifunc_resolver)
+	       ? !ifunc_resolver
+	       : ifunc_resolver
+	       ? !get_alias_target ()->ifunc_resolver
+	       : (alias && analyzed && get_alias_target ()->ifunc_resolver))
 	{
 	  error ("inconsistent %<ifunc%> attribute");
           error_found = true;
@@ -1879,6 +1889,9 @@ symtab_node::resolve_alias (symtab_node *target, bool transparent)
   if (target->implicit_section)
     call_for_symbol_and_aliases (set_implicit_section, NULL, true);
 
+  if (target->ifunc_resolver && !ifunc_resolver)
+    set_ifunc_resolver ();
+
   /* Alias targets become redundant after alias is resolved into an reference.
      We do not want to keep it around or we would have to mind updating them
      when renaming symbols.  */
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 6ae35edc5ae..c6aa7c1745d 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -6262,7 +6262,10 @@ do_assemble_alias (tree decl, tree target)
       maybe_assemble_visibility (decl);
     }
   if (TREE_CODE (decl) == FUNCTION_DECL
-      && cgraph_node::get (decl)->ifunc_resolver)
+      && cgraph_node::get (decl)->ifunc_resolver
+      /* Aliases to the ifunc decl will also have the ifunc_resolver
+	 bit set, so check that this is the ifunc declaration.  */
+      && lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
     {
 #if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
       if (targetm.has_ifunc_p ())

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] [PR83782] ifunc: back-propagate ifunc_resolver to aliases
@ 2023-11-06  6:33 Alexandre Oliva
  0 siblings, 0 replies; 13+ messages in thread
From: Alexandre Oliva @ 2023-11-06  6:33 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:315ccaa54b34cbf8bf7140215e080c26886f1b93

commit 315ccaa54b34cbf8bf7140215e080c26886f1b93
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Mon Aug 8 16:34:18 2022 -0300

    [PR83782] ifunc: back-propagate ifunc_resolver to aliases
    
    gcc.target/i386/mvc10.c fails with -fPIE on ia32 because we omit the
    @PLT mark when calling an alias to an indirect function.  Such aliases
    aren't marked as ifunc_resolvers in the cgraph, so the test that would
    have forced the PLT call fails.
    
    I've arranged for ifunc_resolver to be back-propagated to aliases, and
    relaxed the test that required the ifunc attribute to be attached to
    directly the decl, rather than taken from an aliased decl, when the
    ifunc_resolver bit is set.
    
    
    for  gcc/ChangeLog
    
            PR target/83782
            * cgraph.h (symtab_node::set_ifunc_resolver): New, overloaded.
            Back-propagate flag to aliases.
            * cgraph.cc (cgraph_node::create): Use set_ifunc_resolver.
            (cgraph_node::create_alias): Likewise.
            * lto-cgraph.cc (input_node): Likewise.
            * multiple_target.cc (create_dispatcher_calls): Propagate to
            aliases when redirecting them.
            * symtab.cc (symtab_node::verify_base): Accept ifunc_resolver
            set in an alias to another ifunc_resolver nodes.
            (symtab_node::resolve_alias): Propagate ifunc_resolver from
            resolved target to alias.
            * varasm.cc (do_assemble_alias): Checking for the attribute.

Diff:
---
 gcc/cgraph.cc          |  4 ++--
 gcc/cgraph.h           | 13 +++++++++++++
 gcc/lto-cgraph.cc      |  2 +-
 gcc/multiple_target.cc |  2 ++
 gcc/symtab.cc          | 15 ++++++++++++++-
 gcc/varasm.cc          |  5 ++++-
 6 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index e41e5ad3ae7..046dadf53af 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -518,7 +518,7 @@ cgraph_node::create (tree decl)
     }
 
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
-    node->ifunc_resolver = true;
+    node->set_ifunc_resolver ();
 
   node->register_symbol ();
   maybe_record_nested_function (node);
@@ -576,7 +576,7 @@ cgraph_node::create_alias (tree alias, tree target)
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     alias_node->transparent_alias = alias_node->weakref = true;
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
-    alias_node->ifunc_resolver = true;
+    alias_node->set_ifunc_resolver ();
   return alias_node;
 }
 
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index cedaaac3a45..e118ac75121 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -471,6 +471,19 @@ public:
     return decl->decl_with_vis.symtab_node;
   }
 
+  /* Worked for the nonstatic set_ifunc_resolver, to vback-propagate
+     ifunc_resolver in the alias chain.  */
+  static bool set_ifunc_resolver (symtab_node *n, void * = NULL)
+  {
+    n->ifunc_resolver = true;
+    return false;
+  }
+
+  /* Set the ifunc_resolver bit in this node and in any aliases thereof.  */
+  void set_ifunc_resolver () {
+    call_for_symbol_and_aliases (set_ifunc_resolver, NULL, true);
+  }
+
   /* Try to find a symtab node for declaration DECL and if it does not
      exist or if it corresponds to an inline clone, create a new one.  */
   static inline symtab_node * get_create (tree node);
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index 32c0f5ac6db..e7f77ca7224 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -1294,7 +1294,7 @@ input_node (struct lto_file_decl_data *file_data,
       node = symtab->create_empty ();
       node->decl = fn_decl;
       if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl)))
-	node->ifunc_resolver = 1;
+	node->set_ifunc_resolver ();
       node->register_symbol ();
     }
 
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index a2ed048d7dd..26c73d6a1e4 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -160,6 +160,8 @@ create_dispatcher_calls (struct cgraph_node *node)
 	      source->create_reference (inode, IPA_REF_ALIAS);
 	      if (inode->get_comdat_group ())
 		source->add_to_same_comdat_group (inode);
+	      if (!source->ifunc_resolver)
+		source->set_ifunc_resolver ();
 	    }
 	  else
 	    gcc_unreachable ();
diff --git a/gcc/symtab.cc b/gcc/symtab.cc
index 0470509a98d..b35b879028d 100644
--- a/gcc/symtab.cc
+++ b/gcc/symtab.cc
@@ -1109,9 +1109,19 @@ symtab_node::verify_base (void)
           error ("function symbol is not function");
           error_found = true;
 	}
+      /* If the ifunc attribute is present, the node must be marked as
+	 ifunc_resolver, but it may also be marked on a node that
+	 doesn't have the attribute, if it's an alias to another
+	 marked node.  The resolver node itself is an alias to the
+	 function that performs the resolution proper, and that
+	 function is not marked, but here we test other kinds of
+	 aliases, that alias the indirect function.  */
       else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
 		!= NULL)
-	       != dyn_cast <cgraph_node *> (this)->ifunc_resolver)
+	       ? !ifunc_resolver
+	       : ifunc_resolver
+	       ? !get_alias_target ()->ifunc_resolver
+	       : (alias && analyzed && get_alias_target ()->ifunc_resolver))
 	{
 	  error ("inconsistent %<ifunc%> attribute");
           error_found = true;
@@ -1879,6 +1889,9 @@ symtab_node::resolve_alias (symtab_node *target, bool transparent)
   if (target->implicit_section)
     call_for_symbol_and_aliases (set_implicit_section, NULL, true);
 
+  if (target->ifunc_resolver && !ifunc_resolver)
+    set_ifunc_resolver ();
+
   /* Alias targets become redundant after alias is resolved into an reference.
      We do not want to keep it around or we would have to mind updating them
      when renaming symbols.  */
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 6ae35edc5ae..c6aa7c1745d 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -6262,7 +6262,10 @@ do_assemble_alias (tree decl, tree target)
       maybe_assemble_visibility (decl);
     }
   if (TREE_CODE (decl) == FUNCTION_DECL
-      && cgraph_node::get (decl)->ifunc_resolver)
+      && cgraph_node::get (decl)->ifunc_resolver
+      /* Aliases to the ifunc decl will also have the ifunc_resolver
+	 bit set, so check that this is the ifunc declaration.  */
+      && lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
     {
 #if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
       if (targetm.has_ifunc_p ())

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2024-10-29 21:27 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-15  2:26 [gcc(refs/users/aoliva/heads/testme)] [PR83782] ifunc: back-propagate ifunc_resolver to aliases Alexandre Oliva
  -- strict thread matches above, loose matches on Subject: below --
2024-10-29 21:27 Alexandre Oliva
2023-12-14 16:26 Alexandre Oliva
2023-12-14 13:45 Alexandre Oliva
2023-12-14 12:48 Alexandre Oliva
2023-12-12 20:23 Alexandre Oliva
2023-12-12  2:38 Alexandre Oliva
2023-11-09  1:58 Alexandre Oliva
2023-11-08 23:48 Alexandre Oliva
2023-11-08 19:22 Alexandre Oliva
2023-11-07 11:33 Alexandre Oliva
2023-11-06 18:06 Alexandre Oliva
2023-11-06  6:33 Alexandre Oliva

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).