https://gcc.gnu.org/g:9726eff169f13850e68363d3f8b3fb420339a3b6

commit r16-7847-g9726eff169f13850e68363d3f8b3fb420339a3b6
Author: Alfie Richards <[email protected]>
Date:   Mon Feb 23 13:13:30 2026 +0000

    aarch64: Fix FMV reachability and cgraph_node defintion value [PR 124167]
    
    Fix the reachability checks for FMV nodes which were put in the wrong
    place and fix the definition value for a dispatched symbol to match
    that of the default node.
    
            PR target/124167
    
    gcc/ChangeLog
    
            * attribs.cc (make_dispatcher_decl): Change node->definition
            to inherit from the node its called on.
            * ipa.cc (remote_unreachable_nodes): Move FMV logic out of
            (!in_boundary_p) if block.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/aarch64/pr124167.c: New test.

Diff:
---
 gcc/attribs.cc                              |  6 +++++-
 gcc/ipa.cc                                  | 19 +++++++++----------
 gcc/testsuite/gcc.target/aarch64/pr124167.c |  7 +++++++
 3 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index c63d13d7e550..99f2fd75531a 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -1230,7 +1230,11 @@ make_dispatcher_decl (const tree decl)
   /* Set flags on the cgraph_node for the new decl.  */
   cgraph_node *func_node = cgraph_node::get_create (func_decl);
   func_node->dispatcher_function = true;
-  func_node->definition = true;
+  /* For targets with TARGET_HAS_FMV_TARGET_ATTRIBUTE, the resolver is created
+     unconditionally if any versioned nodes are present.
+     For !TARGET_HAS_FMV_TARGET_ATTRIBUTE, the dispatcher is only defined when
+     the default node is defined.  */
+  func_node->definition = node->definition || TARGET_HAS_FMV_TARGET_ATTRIBUTE;
 
   cgraph_function_version_info *func_v
     = func_node->insert_new_function_version ();
diff --git a/gcc/ipa.cc b/gcc/ipa.cc
index ca939c9c1189..d1a0bb8ce1d0 100644
--- a/gcc/ipa.cc
+++ b/gcc/ipa.cc
@@ -441,16 +441,6 @@ symbol_table::remove_unreachable_nodes (FILE *file)
                    }
                }
 
-             /* A reference to the default node implies use of all the other
-                versions (they get used in the function resolver made later
-                in multiple_target.cc)  */
-             cgraph_function_version_info *node_v = cnode->function_version ();
-             if (node_v && is_function_default_version (node->decl))
-               for (cgraph_function_version_info *fvi = node_v->next;
-                    fvi;
-                    fvi = fvi->next)
-                 enqueue_node (fvi->this_node, &first, &reachable);
-
              for (e = cnode->callees; e; e = e->next_callee)
                {
                  symtab_node *body = e->callee->function_symbol ();
@@ -494,6 +484,15 @@ symbol_table::remove_unreachable_nodes (FILE *file)
          else if (cnode->thunk)
            enqueue_node (cnode->callees->callee, &first, &reachable);
 
+         /* A reference to the default node implies use of all the other
+            versions (they get used in the function resolver made later
+            in multiple_target.cc)  */
+         cgraph_function_version_info *node_v = cnode->function_version ();
+         if (node_v && is_function_default_version (node->decl))
+           for (cgraph_function_version_info *fvi = node_v->next; fvi;
+                fvi = fvi->next)
+             enqueue_node (fvi->this_node, &first, &reachable);
+
          /* If any reachable function has simd clones, mark them as
             reachable as well.  */
          if (cnode->simd_clones)
diff --git a/gcc/testsuite/gcc.target/aarch64/pr124167.c 
b/gcc/testsuite/gcc.target/aarch64/pr124167.c
new file mode 100644
index 000000000000..4ba94b0fe9ac
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr124167.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+
+/* Check there is no ICE.  */
+
+__attribute__ ((target_version ("default"))) int foo ();
+
+int bar () { return foo (); }

Reply via email to