On Oct 29, 2024, Alexandre Oliva <[email protected]> wrote:

> On Nov  8, 2023, Alexandre Oliva <[email protected]> wrote:
>> Ping?

> Ping?
> https://gcc.gnu.org/pipermail/gcc-patches/2023-November/635731.html

> The test still fails with gcc-14 and trunk on ia32 with -fPIE.  I've
> just retested it on trunk on i686-linux-gnu with -fPIE, and on
> x86_64-linux-gnu.

Ping?  Still failing in gcc-15 and trunk on ia32 with PIE enabled by
default.

Patch slightly adjusted to apply cleanly on trunk and gcc-15.  Retested
on both.  Ok for trunk?


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.
---
 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 1a7d49922e097..cb314b5add803 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -672,7 +672,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);
@@ -730,7 +730,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 313610fbe2c6d..67ab59b7ea126 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -499,6 +499,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 4c60bf0dd74a7..d4ab4f7b21cfa 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -1327,7 +1327,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 02353d9dca625..b46c8da0a17d3 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -202,6 +202,8 @@ create_dispatcher_calls (struct cgraph_node *node)
                    source->remove_from_same_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 3dbfad33ea2f8..9f33c6791dde6 100644
--- a/gcc/symtab.cc
+++ b/gcc/symtab.cc
@@ -1124,9 +1124,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;
@@ -1986,6 +1996,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 0d78f5b384fb7..8b0a5d3454678 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -6556,7 +6556,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 ())


-- 
Alexandre Oliva, happy hacker            https://blog.lx.oliva.nom.br/
Free Software Activist     FSFLA co-founder     GNU Toolchain Engineer
More tolerance and less prejudice are key for inclusion and diversity.
Excluding neuro-others for not behaving ""normal"" is *not* inclusive!

Reply via email to