On 6/12/25 11:00 AM, Alfie Richards wrote:
This patch changes the semantics of target_version and target_clones attributes
to match the behavior described in the Arm C Language extension.

The changes to behavior are:

- The scope and signature of an FMV function set is now that of the default
   version.
- The FMV resolver is now created at the locations of the default version
   implementation. Previously this was at the first call to an FMV function.
- When a TU has a single annotated function version, it gets mangled.
   - This includes a lone annotated default version.

This only affects targets with TARRGET_HAS_FMV_TARGET_ATTRIBUTE set to false.
Currently that is aarch64 and riscv.

This is achieved by:

- Skipping the existing FMV dispatching code at C++ gimplification and instead
   making use of the target_clones dispatching code in multiple_targets.cc.
   (This fixes PR target/118313 for aarch64 and riscv).
- Splitting target_clones pass in two, an early and late pass, where the early
   pass handles cases where multiple declarations are used to define a version,
   and the late pass handling target semantics targets, and cases where a FMV
   set is defined by a single target_clones decl.
- Changing the logic in add_candidates and resolve_address of overloaded
   function to prevent resolution of any version except a default version.
   (thus making the default version determine scope and signature of the
   versioned function set).
- Adding logic for dispatching a lone annotated default version in
   multiple_targets.cc
   - As as annotated default version gets mangled an alias is created from the
     dispatched symbol to the default version as no ifunc resolution is required
     in this case. (ie. an alias from `_Z3foov` to `_Z3foov.default`)
- Adding logic to `symbol_table::remove_unreachable_nodes` and analyze_functions
   that a reference to the default function version also implies a possible
   reference to the other versions (so they shouldnt be deleted and do need to
   be analyzed).

gcc/ChangeLog:

        PR target/118313
        * cgraphunit.cc (analyze_functions): Add logic for target version
        dependencies.
        * ipa.cc (symbol_table::remove_unreachable_nodes): Ditto.
        * multiple_target.cc (create_dispatcher_calls): Change to support
        target version semantics.
        (ipa_target_clone): Change to dispatch all function sets in
        target_version semantics, and to have early and late pass.
        (is_simple_target_clones_case): New function.
        * config/aarch64/aarch64.cc: (aarch64_get_function_versions_dispatcher):
        Refactor with the assumption that the DECL node will be default.
        * config/riscv/riscv.cc: (riscv_get_function_versions_dispatcher):
        Refactor with the assumption that the DECL node will be default.
        * passes.def: Split target_clones pass into early and late version.

gcc/cp/ChangeLog:

        PR target/118313
        * call.cc (add_candidates): Change to not resolve non-default versions 
in
        target_version semantics.
        * class.cc (resolve_address_of_overloaded_function): Ditto.
        * cp-gimplify.cc (cp_genericize_r): Change logic to not apply for
        target_version semantics.
        * decl.cc (start_decl): Change to mark and therefore mangle all
        target_version decls.
        (start_preparsed_function): Ditto.
        * typeck.cc (cp_build_function_call_vec): Add error for calling 
unresolvable
        non-default node in target_version semantics.

gcc/testsuite/ChangeLog:

        * g++.target/aarch64/mv-1.C: Change for target_version semantics.
        * g++.target/aarch64/mv-symbols2.C: Ditto.
        * g++.target/aarch64/mv-symbols3.C: Ditto.
        * g++.target/aarch64/mv-symbols4.C: Ditto.
        * g++.target/aarch64/mv-symbols5.C: Ditto.
        * g++.target/aarch64/mvc-symbols3.C: Ditto.
        * g++.target/riscv/mv-symbols2.C: Ditto.
        * g++.target/riscv/mv-symbols3.C: Ditto.
        * g++.target/riscv/mv-symbols4.C: Ditto.
        * g++.target/riscv/mv-symbols5.C: Ditto.
        * g++.target/riscv/mvc-symbols3.C: Ditto.
        * g++.target/aarch64/mv-symbols10.C: New test.
        * g++.target/aarch64/mv-symbols11.C: New test.
        * g++.target/aarch64/mv-symbols12.C: New test.
        * g++.target/aarch64/mv-symbols13.C: New test.
        * g++.target/aarch64/mv-symbols6.C: New test.
        * g++.target/aarch64/mv-symbols7.C: New test.
        * g++.target/aarch64/mv-symbols8.C: New test.
        * g++.target/aarch64/mv-symbols9.C: New test.
---

Just a few nits below, nothing function. So like the prior patch I reviewed today, if this can go in independently now it probably should after fixing the nits.


diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index ac1eb397f01..702539a5512 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -4434,6 +4434,16 @@ cp_build_function_call_vec (tree function, vec<tree, 
va_gc> **params,
        return error_mark_node;
        fndecl = function;
+ /* For target_version semantics, the funciton set cannot be called
s/funciton/function/



diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index 44340cbc6a4..bb430bc4fbf 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -58,8 +58,15 @@ replace_function_decl (tree *op, int *walk_subtrees, void 
*data)
    return NULL;
  }
-/* If the call in NODE has multiple target attribute with multiple fields,
-   replace it with dispatcher call and create dispatcher (once).  */
+/* In target FMV attributes, if the call in NODE has multiple target attribute
+   with multiple fields, replace it with calls to the dispatched symbol and
+   create the disptacher body (once).
Nit.  s/disptacher/dispatcher.




+static bool is_simple_target_clones_case (cgraph_node *node)
Linkage & return type on separate line.  Needs function comment.

+{
+  /* target attribute semantics doesnt support the complex case,
s/doesnt/doesn't/ Or if you don't want the single quote in the comment, then s/doesnt/does not/.



Reply via email to