[gcc r15-7090] Add warning for non-spec compliant FMV in Aarch64

2025-01-21 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:e5798872281de0c4c2e87587cbb562552048ccdb

commit r15-7090-ge5798872281de0c4c2e87587cbb562552048ccdb
Author: Alfie Richards 
Date:   Thu Jan 9 09:45:32 2025 +

Add warning for non-spec compliant FMV in Aarch64

This patch adds a warning when FMV is used for Aarch64.

The reasoning for this is the ACLE [1] spec for FMV has diverged
significantly from the current implementation and we want to prevent
potential future compatability issues.

There is a patch for an ACLE compliant version of target_version and
target_clone in progress but it won't make gcc-15.

This has been bootstrap and regression tested for Aarch64.
Is this okay for master and packport to gcc-14?

[1] 
https://github.com/ARM-software/acle/blob/main/main/acle.md#function-multi-versioning

gcc/ChangeLog:

* config/aarch64/aarch64.cc
(aarch64_process_target_version_attr): Add experimental warning.
* config/aarch64/aarch64.opt: Add command line option to disable
warning.
* doc/invoke.texi: Add documentation for 
-W[no-]experimental-fmv-target.

gcc/testsuite/ChangeLog:

* g++.target/aarch64/mv-1.C: Add CLI flag.
* g++.target/aarch64/mv-symbols1.C: Add CLI flag.
* g++.target/aarch64/mv-symbols2.C: Add CLI flag.
* g++.target/aarch64/mv-symbols3.C: Add CLI flag.
* g++.target/aarch64/mv-symbols4.C: Add CLI flag.
* g++.target/aarch64/mv-symbols5.C: Add CLI flag.
* g++.target/aarch64/mv-warning1.C: New test.
* g++.target/aarch64/mvc-symbols1.C: Add CLI flag.
* g++.target/aarch64/mvc-symbols2.C: Add CLI flag.
* g++.target/aarch64/mvc-symbols3.C: Add CLI flag.
* g++.target/aarch64/mvc-symbols4.C: Add CLI flag.
* g++.target/aarch64/mv-pragma.C: Add CLI flag.
* g++.target/aarch64/mvc-warning1.C: New test.

Diff:
---
 gcc/config/aarch64/aarch64.cc   |  9 +
 gcc/config/aarch64/aarch64.opt  |  4 
 gcc/doc/invoke.texi | 11 ++-
 gcc/testsuite/g++.target/aarch64/mv-1.C |  1 +
 gcc/testsuite/g++.target/aarch64/mv-pragma.C|  1 +
 gcc/testsuite/g++.target/aarch64/mv-symbols1.C  |  1 +
 gcc/testsuite/g++.target/aarch64/mv-symbols2.C  |  1 +
 gcc/testsuite/g++.target/aarch64/mv-symbols3.C  |  1 +
 gcc/testsuite/g++.target/aarch64/mv-symbols4.C  |  1 +
 gcc/testsuite/g++.target/aarch64/mv-symbols5.C  |  1 +
 gcc/testsuite/g++.target/aarch64/mv-warning1.C  |  9 +
 gcc/testsuite/g++.target/aarch64/mvc-symbols1.C |  1 +
 gcc/testsuite/g++.target/aarch64/mvc-symbols2.C |  1 +
 gcc/testsuite/g++.target/aarch64/mvc-symbols3.C |  1 +
 gcc/testsuite/g++.target/aarch64/mvc-symbols4.C |  1 +
 gcc/testsuite/g++.target/aarch64/mvc-warning1.C |  6 ++
 16 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 1dbbc9c3cf9b..dba779a8e51e 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -20257,6 +20257,15 @@ aarch64_parse_fmv_features (const char *str, 
aarch64_feature_flags *isa_flags,
 static bool
 aarch64_process_target_version_attr (tree args)
 {
+  static bool issued_warning = false;
+  if (!issued_warning)
+{
+  warning (OPT_Wexperimental_fmv_target,
+  "Function Multi Versioning support is experimental, and the "
+  "behavior is likely to change");
+  issued_warning = true;
+}
+
   if (TREE_CODE (args) == TREE_LIST)
 {
   if (TREE_CHAIN (args))
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
index da9e0c18d477..7e309d9efe46 100644
--- a/gcc/config/aarch64/aarch64.opt
+++ b/gcc/config/aarch64/aarch64.opt
@@ -431,3 +431,7 @@ handling.  One means we try to form pairs involving one or 
more existing
 individual writeback accesses where possible.  A value of two means we
 also try to opportunistically form writeback opportunities by folding in
 trailing destructive updates of the base register used by a pair.
+
+Wexperimental-fmv-target
+Target Var(warn_experimental_fmv) Warning Init(1)
+Warn about usage of experimental Function Multi Versioning.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 72811042700b..75fbe8838f48 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -827,7 +827,8 @@ Objective-C and Objective-C++ Dialects}.
 -moverride=@var{string}  -mverbose-cost-dump
 -mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{sysreg}
 -mstack-protector-guard-offset=@var{offset} -mtrack-speculation
--moutline-atomics -mearly-ldp-fusion -mlate-ldp-fusion}
+-moutline-atomics -mearly-ldp-fusion -mlate-ldp-fusion
+-Wexperimental-fmv-target}
 
 @emph{Adapteva Epiphany Options} (@ref{Adapteva Epiphany Options})
 @gccoptlist{-mhalf-reg-file  -mprefer

[gcc r15-7099] Regenerate aarch64.opt.urls

2025-01-21 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:1a3a5f5db6603f9212d421bfc48aa7e2922efd00

commit r15-7099-g1a3a5f5db6603f9212d421bfc48aa7e2922efd00
Author: Alfie Richards 
Date:   Tue Jan 21 13:42:05 2025 +

Regenerate aarch64.opt.urls

This updates aarch64.opt.urls after my patch earlier today.

Pushing directly as it's an obvious fix.

gcc/ChangeLog:

* config/aarch64/aarch64.opt.urls: Regenerate

Diff:
---
 gcc/config/aarch64/aarch64.opt.urls | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/config/aarch64/aarch64.opt.urls 
b/gcc/config/aarch64/aarch64.opt.urls
index 4fa903843784..7ec14a943817 100644
--- a/gcc/config/aarch64/aarch64.opt.urls
+++ b/gcc/config/aarch64/aarch64.opt.urls
@@ -92,3 +92,6 @@ 
UrlSuffix(gcc/AArch64-Options.html#index-mstack-protector-guard-reg)
 mstack-protector-guard-offset=
 UrlSuffix(gcc/AArch64-Options.html#index-mstack-protector-guard-offset)
 
+Wexperimental-fmv-target
+UrlSuffix(gcc/AArch64-Options.html#index-Wexperimental-fmv-target)
+


[gcc r15-7101] MAINTAINERS: add myself to write after approval

2025-01-21 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:ddc65177bb5a799acb8b17181ca8275acc462a81

commit r15-7101-gddc65177bb5a799acb8b17181ca8275acc462a81
Author: Alfie Richards 
Date:   Tue Jan 21 13:53:29 2025 +

MAINTAINERS: add myself to write after approval

ChangeLog:

* MAINTAINERS: Add myself to write after approval.

Diff:
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 256a03957d59..44367b27b415 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -749,6 +749,7 @@ Fritz Reese foreese 

 Volker Reichelt reichelt
 Joern Rennecke  amylaar 
 Bernhard Reutner-Fischeraldot   
+Alfie Richards  -   
 Torvald Riegel  torvald 
 Tom Rix -   
 Pierre-Marie de Rodat   pmderodat   


[gcc r12-11010] aarch64: Use PAUTH instead of V8_3A in some places

2025-04-01 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:0c66b2f14b5d4cd46388d79b4a73a77433e1dd22

commit r12-11010-g0c66b2f14b5d4cd46388d79b4a73a77433e1dd22
Author: Andrew Carlotti 
Date:   Tue Jul 30 16:26:04 2024 +0100

aarch64: Use PAUTH instead of V8_3A in some places

gcc/ChangeLog:

PR target/119372
* config/aarch64/aarch64.cc
(aarch64_expand_epilogue): Use TARGET_PAUTH.
* config/aarch64/aarch64.md: Update comment.

(cherry-picked from commit 20385cb92cbd4a1934661ab97a162c1e25935836)

Diff:
---
 gcc/config/aarch64/aarch64.cc | 6 +++---
 gcc/config/aarch64/aarch64.md | 8 
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 72d737d62228..74d74976f4a3 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -10048,12 +10048,12 @@ aarch64_expand_epilogue (bool for_sibcall)
1) Sibcalls don't return in a normal way, so if we're about to call one
   we must authenticate.
 
-   2) The RETAA instruction is not available before ARMv8.3-A, so if we are
-  generating code for !TARGET_ARMV8_3 we can't use it and must
+   2) The RETAA instruction is not available without FEAT_PAuth, so if we
+  are generating code for !TARGET_PAUTH we can't use it and must
   explicitly authenticate.
 */
   if (aarch64_return_address_signing_enabled ()
-  && (for_sibcall || !TARGET_ARMV8_3))
+  && (for_sibcall || !TARGET_PAUTH))
 {
   switch (aarch64_ra_sign_key)
{
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 47b70feff02b..0b205b43d97d 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -7124,11 +7124,11 @@
   [(set_attr "type" "f_cvtf2i")]
 )
 
-;; Pointer authentication patterns are always provided.  In architecture
-;; revisions prior to ARMv8.3-A these HINT instructions operate as NOPs.
+;; Pointer authentication patterns are always provided.  On targets that
+;; don't implement FEAT_PAuth these HINT instructions operate as NOPs.
 ;; This lets the user write portable software which authenticates pointers
-;; when run on something which implements ARMv8.3-A, and which runs
-;; correctly, but does not authenticate pointers, where ARMv8.3-A is not
+;; when run on something which implements FEAT_PAuth, and which runs
+;; correctly, but does not authenticate pointers, where FEAT_PAuth is not
 ;; implemented.
 
 ;; Signing/Authenticating R30 using SP as the salt.


[gcc(refs/users/alfierichards/heads/fmv_c)] Change target_version semantics to follow ACLE specification.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:9a206e0522b42342b7356369d0d77f28c044f091

commit 9a206e0522b42342b7356369d0d77f28c044f091
Author: Alfie Richards 
Date:   Thu Feb 13 15:30:45 2025 +

Change target_version semantics to follow ACLE specification.

This changes behavior of target_clones and target_version attributes
to be inline with what is specified in the Arm C Language Extension.

Notably this changes the scope and signature of multiversioned functions
to that of the default version, and changes the resolver to be
created at the implementation of the default version.

This is achieved by changing the C++ front end to no longer resolve any
non-default version decls in lookup, and by moving dipatching
for default_target sets to reuse the dispatching logic for target_clones
in multiple_target.cc.

The dispatching in create_dispatcher_calls is changed for the case of
a lone annotated default function to change the dispatched symbol to
be an alias for the mangled default function.

gcc/ChangeLog:

* 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.

gcc/cp/ChangeLog:

* 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.

Diff:
---
 gcc/cgraphunit.cc   |  9 +++
 gcc/cp/call.cc  | 10 
 gcc/cp/class.cc | 13 -
 gcc/cp/cp-gimplify.cc   | 11 ++--
 gcc/cp/decl.cc  | 14 +
 gcc/cp/typeck.cc| 10 
 gcc/ipa.cc  | 11 
 gcc/multiple_target.cc  | 73 +
 gcc/testsuite/g++.target/aarch64/mv-1.C |  4 ++
 gcc/testsuite/g++.target/aarch64/mv-symbols10.C | 27 +
 gcc/testsuite/g++.target/aarch64/mv-symbols11.C | 30 ++
 gcc/testsuite/g++.target/aarch64/mv-symbols12.C | 28 ++
 gcc/testsuite/g++.target/aarch64/mv-symbols13.C | 28 ++
 gcc/testsuite/g++.target/aarch64/mv-symbols2.C  | 12 ++--
 gcc/testsuite/g++.target/aarch64/mv-symbols3.C  |  6 +-
 gcc/testsuite/g++.target/aarch64/mv-symbols4.C  |  6 +-
 gcc/testsuite/g++.target/aarch64/mv-symbols5.C  |  6 +-
 gcc/testsuite/g++.target/aarch64/mv-symbols6.C  | 25 +
 gcc/testsuite/g++.target/aarch64/mv-symbols7.C  | 48 
 gcc/testsuite/g++.target/aarch64/mv-symbols8.C  | 46 
 gcc/testsuite/g++.target/aarch64/mv-symbols9.C  | 43 +++
 gcc/testsuite/g++.target/aarch64/mvc-symbols3.C | 12 ++--
 gcc/testsuite/g++.target/riscv/mv-symbols2.C| 12 ++--
 gcc/testsuite/g++.target/riscv/mv-symbols3.C|  6 +-
 gcc/testsuite/g++.target/riscv/mv-symbols4.C|  6 +-
 gcc/testsuite/g++.target/riscv/mv-symbols5.C|  6 +-
 gcc/testsuite/g++.target/riscv/mvc-symbols3.C   | 12 ++--
 27 files changed, 456 insertions(+), 58 deletions(-)

diff --git

[gcc(refs/users/alfierichards/heads/fmv_c)] Refactor FMV name mangling.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:fcce1c2be2d17cb138ec6869be319da39b51c7a8

commit fcce1c2be2d17cb138ec6869be319da39b51c7a8
Author: Alfie Richards 
Date:   Wed Feb 12 14:13:02 2025 +

Refactor FMV name mangling.

This patch is an overhaul of how FMV name mangling works. Previously
mangling logic was duplicated in several places across both target
specific and independent code. This patch changes this such that all
mangling is done in targetm.mangle_decl_assembler_name (including for the
dispatched symbol and dispatcher resolver).

This allows for the removing of previous hacks, such as where the default
mangled decl's assembler name was unmangled to then remangle all versions
and the resolver and dispatched symbol.

This does introduce a change though (shown in test changes) where
previously x86 for target annotated FMV sets set the function name to
the assembler name and remangled this. This was hard to reproduce without
resorting to hacks I wasn't comfortable with so the mangling is changed
to append ".ifunc" which matches clang.

This change also refactors expand_target_clone using
targetm.mangle_decl_assembler_name for mangling and get_clone_versions.

gcc/ChangeLog:

* attribs.cc (make_dispatcher_decl): Move duplicated cgraph logic 
into
this function and change to use targetm.mangle_decl_assembler_name 
for
mangling.
* config/aarch64/aarch64.cc (aarch64_parse_fmv_features): Change to
support string_slice.
(aarch64_process_target_version_attr): Ditto.
(get_feature_mask_for_version): Ditto.
(aarch64_mangle_decl_assembler_name): Add logic for mangling 
dispatched
symbol and resolver.
(get_suffixed_assembler_name): Removed.
(make_resolver_func): Refactor to use
aarch64_mangle_decl_assembler_name for mangling.
(aarch64_generate_version_dispatcher_body): Remove remangling.
(aarch64_get_function_versions_dispatcher): Refactor to remove
duplicated cgraph logic.
* config/i386/i386-features.cc (is_valid_asm_symbol): Moved from
multiple_target.cc.
(create_new_asm_name): Ditto.
(ix86_mangle_function_version_assembler_name): Refactor to use
clone_identifier and to mangle default.
(ix86_mangle_decl_assembler_name): Add logic for mangling dispatched
symbol and resolver.
(ix86_get_function_versions_dispatcher): Remove duplicated cgraph
logic.
(make_resolver_func): Refactor to use 
ix86_mangle_decl_assembler_name
for mangling.
* config/riscv/riscv.cc (riscv_mangle_decl_assembler_name): Add 
logic
for FMV mangling.
(get_suffixed_assembler_name): Removed.
(make_resolver_func): Refactor to use 
riscv_mangle_decl_assembler_name
for mangling.
(riscv_generate_version_dispatcher_body): Remove unnecessary 
remangling.
(riscv_get_function_versions_dispatcher): Remove duplicated cgraph
logic.
* config/rs6000/rs6000.cc (rs6000_mangle_decl_assembler_name): New
function.
(rs6000_get_function_versions_dispatcher): Remove duplicated cgraph
logic.
(make_resolver_func): Refactor to use 
rs6000_mangle_decl_assembler_name
for mangling.
(is_valid_asm_symbol): Move from multiple_target.cc.
(create_new_asm_name): Ditto.
(rs6000_mangle_function_version_assembler_name): New function.
* multiple_target.cc (create_dispatcher_calls): Remove mangling 
code.
(get_attr_str): Removed.
(separate_attrs): Ditto.
(is_valid_asm_symbol): Moved to target specific.
(create_new_asm_name): Ditto.
(expand_target_clones): Refactor to use
targetm.mangle_decl_assembler_name for mangling and be more general.
* tree.cc (get_target_clone_attr_len): Removed.
* tree.h (get_target_clone_attr_len): Removed.

gcc/cp/ChangeLog:

* decl.cc (maybe_mark_function_versioned): Change to insert 
function version
and therefore record assembler name.

gcc/testsuite/ChangeLog:

* g++.target/i386/mv-symbols1.C: Update x86 FMV mangling.
* g++.target/i386/mv-symbols3.C: Ditto.
* g++.target/i386/mv-symbols4.C: Ditto.
* g++.target/i386/mv-symbols5.C: Ditto.

Diff:
---
 gcc/attribs.cc  |  44 --
 gcc/config/aarch64/aarch64.cc   | 160 -
 gcc/config/i386/i386-features.cc| 108 +-
 gcc/config/riscv/riscv.cc   | 101 +
 gcc/config/rs6000/rs6000.cc | 115 ---
 gcc/

[gcc(refs/users/alfierichards/heads/fmv_c)] Update is_function_default_version to work with target_version.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:4a1e6acecf55e8d4b008fdf4efba6160e9cd1108

commit 4a1e6acecf55e8d4b008fdf4efba6160e9cd1108
Author: Alfie Richards 
Date:   Fri Jan 31 10:47:14 2025 +

Update is_function_default_version to work with target_version.

Notably this respects target_version semantics where an unannotated
function can be the default version.

gcc/ChangeLog:

* attribs.cc (is_function_default_version): Add target_version 
logic.

Diff:
---
 gcc/attribs.cc | 27 ---
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 56dd18c2fa8e..f6667839c013 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -1279,18 +1279,31 @@ make_dispatcher_decl (const tree decl)
   return func_decl;
 }
 
-/* Returns true if DECL is multi-versioned using the target attribute, and this
-   is the default version.  This function can only be used for targets that do
-   not support the "target_version" attribute.  */
+/* Returns true if DECL a multiversioned default.
+   With the target attribute semantics, returns true if the function is marked
+   as default with the target version.
+   With the target_version attribute semantics, returns true if the function
+   is either not annotated, or annotated as default.  */
 
 bool
 is_function_default_version (const tree decl)
 {
-  if (TREE_CODE (decl) != FUNCTION_DECL
-  || !DECL_FUNCTION_VERSIONED (decl))
+  tree attr;
+  if (TREE_CODE (decl) != FUNCTION_DECL)
 return false;
-  tree attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
-  gcc_assert (attr);
+  if (TARGET_HAS_FMV_TARGET_ATTRIBUTE)
+{
+  if (!DECL_FUNCTION_VERSIONED (decl))
+   return false;
+  attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
+  gcc_assert (attr);
+}
+  else
+{
+  attr = lookup_attribute ("target_version", DECL_ATTRIBUTES (decl));
+  if (!attr)
+   return true;
+}
   attr = TREE_VALUE (TREE_VALUE (attr));
   return (TREE_CODE (attr) == STRING_CST
  && strcmp (TREE_STRING_POINTER (attr), "default") == 0);


[gcc(refs/users/alfierichards/heads/fmv_c)] Remove FMV beta warning.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:9f857996ad74fabf86f174b5cc6b8052d7131fa8

commit 9f857996ad74fabf86f174b5cc6b8052d7131fa8
Author: Alfie Richards 
Date:   Thu Feb 13 16:52:28 2025 +

Remove FMV beta warning.

This patch removes the warning for target_version and target_clones
in aarch64 as it is now spec compliant.

gcc/ChangeLog:

* config/aarch64/aarch64.cc (aarch64_process_target_version_attr):
Remove warning.
* config/aarch64/aarch64.opt: Mark -Wno-experimental-fmv-target
deprecated.
* doc/invoke.texi: Ditto.

gcc/testsuite/ChangeLog:

* g++.target/aarch64/mv-1.C: Remove option.
* g++.target/aarch64/mv-and-mvc-error1.C: Ditto.
* g++.target/aarch64/mv-and-mvc-error2.C: Ditto.
* g++.target/aarch64/mv-and-mvc-error3.C: Ditto.
* g++.target/aarch64/mv-and-mvc1.C: Ditto.
* g++.target/aarch64/mv-and-mvc2.C: Ditto.
* g++.target/aarch64/mv-and-mvc3.C: Ditto.
* g++.target/aarch64/mv-and-mvc4.C: Ditto.
* g++.target/aarch64/mv-error1.C: Ditto.
* g++.target/aarch64/mv-error2.C: Ditto.
* g++.target/aarch64/mv-error3.C: Ditto.
* g++.target/aarch64/mv-error4.C: Ditto.
* g++.target/aarch64/mv-error5.C: Ditto.
* g++.target/aarch64/mv-error6.C: Ditto.
* g++.target/aarch64/mv-error7.C: Ditto.
* g++.target/aarch64/mv-error8.C: Ditto.
* g++.target/aarch64/mv-pragma.C: Ditto.
* g++.target/aarch64/mv-symbols1.C: Ditto.
* g++.target/aarch64/mv-symbols10.C: Ditto.
* g++.target/aarch64/mv-symbols11.C: Ditto.
* g++.target/aarch64/mv-symbols12.C: Ditto.
* g++.target/aarch64/mv-symbols13.C: Ditto.
* 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/mv-symbols6.C: Ditto.
* g++.target/aarch64/mv-symbols7.C: Ditto.
* g++.target/aarch64/mv-symbols8.C: Ditto.
* g++.target/aarch64/mv-symbols9.C: Ditto.
* g++.target/aarch64/mvc-error1.C: Ditto.
* g++.target/aarch64/mvc-error2.C: Ditto.
* g++.target/aarch64/mvc-symbols1.C: Ditto.
* g++.target/aarch64/mvc-symbols2.C: Ditto.
* g++.target/aarch64/mvc-symbols3.C: Ditto.
* g++.target/aarch64/mvc-symbols4.C: Ditto.
* g++.target/aarch64/mv-warning1.C: Removed.
* g++.target/aarch64/mvc-warning1.C: Removed.

Diff:
---
 gcc/config/aarch64/aarch64.cc| 9 -
 gcc/config/aarch64/aarch64.opt   | 2 +-
 gcc/doc/invoke.texi  | 5 +
 gcc/testsuite/g++.target/aarch64/mv-1.C  | 1 -
 gcc/testsuite/g++.target/aarch64/mv-and-mvc-error1.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-and-mvc-error2.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-and-mvc-error3.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-and-mvc1.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-and-mvc2.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-and-mvc3.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-and-mvc4.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-error1.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-error2.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-error3.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-error4.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-error5.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-error6.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-error7.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-error8.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-pragma.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols1.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols10.C  | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols11.C  | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols12.C  | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols13.C  | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols2.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols3.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols4.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols5.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols6.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols7.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols8.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols9.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-warning1.C   | 9 -
 gcc/testsuite/g++.target/aarch64/mvc-error1.C| 1 -
 gcc/testsuite/g++.target/aarch64/mvc-error2.C| 1 -
 gcc/testsuite/g++.target/aarch64/mvc-symbols1.C  | 1 -
 gcc/t

[gcc(refs/users/alfierichards/heads/fmv_c)] c: Add target_version attribute support.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:2a3abe41cbd4b8d6b509b72f086ff1b58fb285de

commit 2a3abe41cbd4b8d6b509b72f086ff1b58fb285de
Author: Alfie Richards 
Date:   Wed Apr 2 13:37:02 2025 +

c: Add target_version attribute support.

This commit introduces support for the target_version attribute in the c
frontend, following the behavior defined in the Arm C Language Extension.

Key changes include:

- During pushdecl, the compiler now checks whether the current symbol is
  part of a multiversioned set.
  - New versions are added to the function multiversioning (FMV) set, and 
the
symbol binding is updated to include the default version (if present).
This means the binding for a multiversioned symbol will always reference
the default version (if present), as it defines the scope and signature
for the entire set.
  - Pre-existing versions are merged with their previous version (or 
diagnosed).
- Lookup logic is adjusted to prevent resolving non-default versions.
- start_decl and start_function are updated to handle marking and mangling 
of
  versioned functions.
- c_parse_final_cleanups now includes a call to process_same_body_aliases.
  This has no functional impact other than setting cpp_implicit_aliases_done
  on all nodes, which is necessary for certain shared FMV logic.

gcc/c/ChangeLog:

* c-decl.cc (maybe_mark_function_versioned): New function.
(merge_decls): Preserve DECL_FUNCTION_VERSIONED in merging.
(duplicate_decls): Add check and diagnostic for unmergable version 
decls.
(pushdecl): Add FMV target_version logic.
(lookup_name): Dont resolve non-default versions.
(start_decl): Mark and mangle versioned functions.
(start_function): Mark and mangle versioned functions.
(c_parse_final_cleanups): Add call to process_same_body_aliases.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/mv-1.c: New test.
* gcc.target/aarch64/mv-and-mvc1.c: New test.
* gcc.target/aarch64/mv-and-mvc2.c: New test.
* gcc.target/aarch64/mv-and-mvc3.c: New test.
* gcc.target/aarch64/mv-and-mvc4.c: New test.
* gcc.target/aarch64/mv-symbols1.c: New test.
* gcc.target/aarch64/mv-symbols10.c: New test.
* gcc.target/aarch64/mv-symbols11.c: New test.
* gcc.target/aarch64/mv-symbols12.c: New test.
* gcc.target/aarch64/mv-symbols13.c: New test.
* gcc.target/aarch64/mv-symbols2.c: New test.
* gcc.target/aarch64/mv-symbols3.c: New test.
* gcc.target/aarch64/mv-symbols4.c: New test.
* gcc.target/aarch64/mv-symbols5.c: New test.
* gcc.target/aarch64/mv-symbols6.c: New test.
* gcc.target/aarch64/mv-symbols7.c: New test.
* gcc.target/aarch64/mv-symbols8.c: New test.
* gcc.target/aarch64/mv-symbols9.c: New test.
* gcc.target/aarch64/mvc-symbols1.c: New test.
* gcc.target/aarch64/mvc-symbols2.c: New test.
* gcc.target/aarch64/mvc-symbols3.c: New test.
* gcc.target/aarch64/mvc-symbols4.c: New test.

Diff:
---
 gcc/c/c-decl.cc | 117 
 gcc/testsuite/gcc.target/aarch64/mv-1.c |  43 +
 gcc/testsuite/gcc.target/aarch64/mv-and-mvc1.c  |  37 
 gcc/testsuite/gcc.target/aarch64/mv-and-mvc2.c  |  28 ++
 gcc/testsuite/gcc.target/aarch64/mv-and-mvc3.c  |  40 
 gcc/testsuite/gcc.target/aarch64/mv-and-mvc4.c  |  37 
 gcc/testsuite/gcc.target/aarch64/mv-symbols1.c  |  38 
 gcc/testsuite/gcc.target/aarch64/mv-symbols10.c |  42 +
 gcc/testsuite/gcc.target/aarch64/mv-symbols11.c |  16 
 gcc/testsuite/gcc.target/aarch64/mv-symbols12.c |  27 ++
 gcc/testsuite/gcc.target/aarch64/mv-symbols13.c |  28 ++
 gcc/testsuite/gcc.target/aarch64/mv-symbols2.c  |  28 ++
 gcc/testsuite/gcc.target/aarch64/mv-symbols3.c  |  27 ++
 gcc/testsuite/gcc.target/aarch64/mv-symbols4.c  |  31 +++
 gcc/testsuite/gcc.target/aarch64/mv-symbols5.c  |  36 
 gcc/testsuite/gcc.target/aarch64/mv-symbols6.c  |  20 
 gcc/testsuite/gcc.target/aarch64/mv-symbols7.c  |  47 ++
 gcc/testsuite/gcc.target/aarch64/mv-symbols8.c  |  47 ++
 gcc/testsuite/gcc.target/aarch64/mv-symbols9.c  |  44 +
 gcc/testsuite/gcc.target/aarch64/mvc-symbols1.c |  25 +
 gcc/testsuite/gcc.target/aarch64/mvc-symbols2.c |  15 +++
 gcc/testsuite/gcc.target/aarch64/mvc-symbols3.c |  19 
 gcc/testsuite/gcc.target/aarch64/mvc-symbols4.c |  12 +++
 23 files changed, 804 insertions(+)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index c778c7febfa0..977e6ef37878 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -2087,6 +2087,29 @@ previous_tag (tree type)
   return NULL_TREE;
 }
 
+/* Subr

[gcc(refs/users/alfierichards/heads/fmv_c)] c: Improve diagnostics for C FMV declaration conflicts.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:2061ee1fbd17cadf7b840e03c6e881d0c508a296

commit 2061ee1fbd17cadf7b840e03c6e881d0c508a296
Author: Alfie Richards 
Date:   Wed Apr 2 14:24:00 2025 +

c: Improve diagnostics for C FMV declaration conflicts.

Improves diagnostic messages for conflicting function multiversioning (FMV)
declarations using target_version and/or target_clones attributes.

Conflict errors now include the overlapping version string (if relevant),
making it easier to identify and resolve declaration mismatches.

gcc/c/ChangeLog:

* c-decl.cc (diagnose_mismatched_decls): Add conflicting_ver 
argument
and update diagnostics with it.
(duplicate_decls): Ditto.
(pushdecl): Add conflicting_version variable update logic to use it.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/mv-and-mvc-error1.c: New test.
* gcc.target/aarch64/mv-and-mvc-error2.c: New test.
* gcc.target/aarch64/mv-and-mvc-error3.c: New test.
* gcc.target/aarch64/mv-error1.c: New test.
* gcc.target/aarch64/mv-error2.c: New test.
* gcc.target/aarch64/mv-error3.c: New test.
* gcc.target/aarch64/mv-error4.c: New test.
* gcc.target/aarch64/mv-error5.c: New test.
* gcc.target/aarch64/mv-error6.c: New test.
* gcc.target/aarch64/mv-error7.c: New test.
* gcc.target/aarch64/mv-error8.c: New test.
* gcc.target/aarch64/mv-error9.c: New test.
* gcc.target/aarch64/mvc-error1.c: New test.
* gcc.target/aarch64/mvc-error2.c: New test.
* gcc.target/aarch64/mvc-warning1.c: New test.

Diff:
---
 gcc/c/c-decl.cc| 37 --
 .../gcc.target/aarch64/mv-and-mvc-error1.c |  9 ++
 .../gcc.target/aarch64/mv-and-mvc-error2.c |  9 ++
 .../gcc.target/aarch64/mv-and-mvc-error3.c |  8 +
 gcc/testsuite/gcc.target/aarch64/mv-error1.c   | 18 +++
 gcc/testsuite/gcc.target/aarch64/mv-error2.c   |  9 ++
 gcc/testsuite/gcc.target/aarch64/mv-error3.c   | 12 +++
 gcc/testsuite/gcc.target/aarch64/mv-error4.c   |  9 ++
 gcc/testsuite/gcc.target/aarch64/mv-error5.c   |  8 +
 gcc/testsuite/gcc.target/aarch64/mv-error6.c   | 20 
 gcc/testsuite/gcc.target/aarch64/mv-error7.c   | 11 +++
 gcc/testsuite/gcc.target/aarch64/mv-error8.c   | 12 +++
 gcc/testsuite/gcc.target/aarch64/mv-error9.c   | 12 +++
 gcc/testsuite/gcc.target/aarch64/mvc-error1.c  |  9 ++
 gcc/testsuite/gcc.target/aarch64/mvc-error2.c  |  9 ++
 gcc/testsuite/gcc.target/aarch64/mvc-warning1.c| 13 
 16 files changed, 195 insertions(+), 10 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 977e6ef37878..915743eb5ec3 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -2119,8 +2119,8 @@ maybe_mark_function_versioned (tree decl)
TREE_TYPE (NEWDECL, OLDDECL) respectively.  */
 
 static bool
-diagnose_mismatched_decls (tree newdecl, tree olddecl,
-  tree *newtypep, tree *oldtypep)
+diagnose_mismatched_decls (tree newdecl, tree olddecl, tree *newtypep,
+  tree *oldtypep, string_slice *conflicting_ver = NULL)
 {
   tree newtype, oldtype;
   bool retval = true;
@@ -2448,7 +2448,12 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
DECL_ATTRIBUTES (newdecl)
{
  auto_diagnostic_group d;
- error ("redefinition of %q+D", newdecl);
+ if (conflicting_ver && conflicting_ver->is_valid ())
+   error ("redefinition of %qB version for %q+D",
+  conflicting_ver,
+  newdecl);
+ else
+   error ("redefinition of %q+D", newdecl);
  locate_old_decl (olddecl);
  return false;
}
@@ -3188,20 +3193,29 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, 
tree oldtype)
true.  Otherwise, return false.  */
 
 static bool
-duplicate_decls (tree newdecl, tree olddecl)
+duplicate_decls (tree newdecl, tree olddecl,
+string_slice *conflicting_ver = NULL)
 {
   tree newtype = NULL, oldtype = NULL;
 
   if (!TARGET_HAS_FMV_TARGET_ATTRIBUTE
+  && TREE_CODE (olddecl) == FUNCTION_DECL
+  && TREE_CODE (newdecl) == FUNCTION_DECL
   && !mergeable_version_decls (olddecl, newdecl))
 {
   auto_diagnostic_group d;
-  error ("conflicting versioned declarations of %q+D", newdecl);
+  if (conflicting_ver && conflicting_ver->is_valid ())
+   error ("conflicting %qB version declarations of %q+D",
+  conflicting_ver,
+  newdecl);
+  else
+   error ("conflicting versioned declarations of %q+D", new

[gcc(refs/users/alfierichards/heads/fmv_c)] Add x86 FMV symbol tests

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:5c3d8e4a4e73b4dd32b3c03334cd1d97b9bda9db

commit 5c3d8e4a4e73b4dd32b3c03334cd1d97b9bda9db
Author: Alice Carlotti 
Date:   Tue Jan 28 15:17:33 2025 +

Add x86 FMV symbol tests

This is for testing the x86 mangling of FMV versioned function
assembly names.

gcc/testsuite/ChangeLog:

* g++.target/i386/mv-symbols1.C: New test.
* g++.target/i386/mv-symbols2.C: New test.
* g++.target/i386/mv-symbols3.C: New test.
* g++.target/i386/mv-symbols4.C: New test.
* g++.target/i386/mv-symbols5.C: New test.
* g++.target/i386/mvc-symbols1.C: New test.
* g++.target/i386/mvc-symbols2.C: New test.
* g++.target/i386/mvc-symbols3.C: New test.
* g++.target/i386/mvc-symbols4.C: New test.

Co-authored-by: Alfie Richards 

Diff:
---
 gcc/testsuite/g++.target/i386/mv-symbols1.C  | 68 
 gcc/testsuite/g++.target/i386/mv-symbols2.C  | 56 +++
 gcc/testsuite/g++.target/i386/mv-symbols3.C  | 44 ++
 gcc/testsuite/g++.target/i386/mv-symbols4.C  | 50 
 gcc/testsuite/g++.target/i386/mv-symbols5.C  | 56 +++
 gcc/testsuite/g++.target/i386/mvc-symbols1.C | 44 ++
 gcc/testsuite/g++.target/i386/mvc-symbols2.C | 29 
 gcc/testsuite/g++.target/i386/mvc-symbols3.C | 35 ++
 gcc/testsuite/g++.target/i386/mvc-symbols4.C | 23 ++
 9 files changed, 405 insertions(+)

diff --git a/gcc/testsuite/g++.target/i386/mv-symbols1.C 
b/gcc/testsuite/g++.target/i386/mv-symbols1.C
new file mode 100644
index ..1290299aea5e
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/mv-symbols1.C
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O0" } */
+
+__attribute__((target("default")))
+int foo ()
+{
+  return 1;
+}
+
+__attribute__((target("arch=slm")))
+int foo ()
+{
+  return 3;
+}
+
+__attribute__((target("sse4.2")))
+int foo ()
+{
+  return 5;
+}
+
+__attribute__((target("sse4.2")))
+int foo (int)
+{
+  return 6;
+}
+
+__attribute__((target("arch=slm")))
+int foo (int)
+{
+  return 4;
+}
+
+__attribute__((target("default")))
+int foo (int)
+{
+  return 2;
+}
+
+int bar()
+{
+  return foo ();
+}
+
+int bar(int x)
+{
+  return foo (x);
+}
+
+/* When updating any of the symbol names in these tests, make sure to also
+   update any tests for their absence in mvc-symbolsN.C */
+
+/* { dg-final { scan-assembler-times "\n_Z3foov:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.arch_slm:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.sse4.2:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\tcall\t_Z7_Z3foovv\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.type\t_Z7_Z3foovv, 
@gnu_indirect_function\n" 1 } } */
+/* { dg-final { scan-assembler-times 
"\n\t\.set\t_Z7_Z3foovv,_Z3foov\.resolver\n" 1 } } */
+
+/* { dg-final { scan-assembler-times "\n_Z3fooi:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.arch_slm:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.sse4.2:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\tcall\t_Z7_Z3fooii\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.type\t_Z7_Z3fooii, 
@gnu_indirect_function\n" 1 } } */
+/* { dg-final { scan-assembler-times 
"\n\t\.set\t_Z7_Z3fooii,_Z3fooi\.resolver\n" 1 } } */
diff --git a/gcc/testsuite/g++.target/i386/mv-symbols2.C 
b/gcc/testsuite/g++.target/i386/mv-symbols2.C
new file mode 100644
index ..8b75565d78d0
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/mv-symbols2.C
@@ -0,0 +1,56 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O0" } */
+
+__attribute__((target("default")))
+int foo ()
+{
+  return 1;
+}
+
+__attribute__((target("arch=slm")))
+int foo ()
+{
+  return 3;
+}
+
+__attribute__((target("sse4.2")))
+int foo ()
+{
+  return 5;
+}
+
+__attribute__((target("sse4.2")))
+int foo (int)
+{
+  return 6;
+}
+
+__attribute__((target("arch=slm")))
+int foo (int)
+{
+  return 4;
+}
+
+__attribute__((target("default")))
+int foo (int)
+{
+  return 2;
+}
+
+/* When updating any of the symbol names in these tests, make sure to also
+   update any tests for their absence in mvc-symbolsN.C */
+
+/* { dg-final { scan-assembler-times "\n_Z3foov:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.arch_slm:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.sse4.2:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 0 } } */
+/* { dg-final { scan-assembler-times "\n\t\.type\t_Z7_Z3foovv, 
@gnu_indirect_function\n" 0 } } */
+/* { dg-final { scan-assembler-times 
"\n\t\.set\t_Z7_Z3foovv,_Z3foov\.resolver\n" 0 } } */
+
+/* { dg-final { scan-assembler-

[gcc] Created branch 'alfierichards/heads/fmv_c' in namespace 'refs/users'

2025-04-07 Thread Alfie Richards via Gcc-cvs
The branch 'alfierichards/heads/fmv_c' was created in namespace 'refs/users' 
pointing to:

 2061ee1fbd17... c: Improve diagnostics for C FMV declaration conflicts.


[gcc(refs/users/alfierichards/heads/fmv_c)] Add PowerPC FMV symbol tests.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:d5b12f31d02063d4d7c8051887b44d6b6bc62ef7

commit d5b12f31d02063d4d7c8051887b44d6b6bc62ef7
Author: Alice Carlotti 
Date:   Tue Jan 28 15:16:31 2025 +

Add PowerPC FMV symbol tests.

This tests the mangling of function assembly names when annotated with
target_clones attributes.

gcc/testsuite/ChangeLog:

* g++.target/powerpc/mvc-symbols1.C: New test.
* g++.target/powerpc/mvc-symbols2.C: New test.
* g++.target/powerpc/mvc-symbols3.C: New test.
* g++.target/powerpc/mvc-symbols4.C: New test.

Co-authored-by: Alfie Richards 

Diff:
---
 gcc/testsuite/g++.target/powerpc/mvc-symbols1.C | 47 +
 gcc/testsuite/g++.target/powerpc/mvc-symbols2.C | 35 ++
 gcc/testsuite/g++.target/powerpc/mvc-symbols3.C | 41 +
 gcc/testsuite/g++.target/powerpc/mvc-symbols4.C | 29 +++
 4 files changed, 152 insertions(+)

diff --git a/gcc/testsuite/g++.target/powerpc/mvc-symbols1.C 
b/gcc/testsuite/g++.target/powerpc/mvc-symbols1.C
new file mode 100644
index ..9424382bf141
--- /dev/null
+++ b/gcc/testsuite/g++.target/powerpc/mvc-symbols1.C
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O0" } */
+
+__attribute__((target_clones("default", "cpu=power6", "cpu=power6x")))
+int foo ()
+{
+  return 1;
+}
+
+__attribute__((target_clones("cpu=power6x", "cpu=power6", "default")))
+int foo (int)
+{
+  return 2;
+}
+
+int bar()
+{
+  return foo ();
+}
+
+int bar(int x)
+{
+  return foo (x);
+}
+
+/* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.cpu_power6:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.cpu_power6x:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\tbl _Z3foov\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, 
@gnu_indirect_function\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 
1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3foov\.default\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3foov\.cpu_power6\n" 1 } } 
*/
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3foov\.cpu_power6x\n" 0 } 
} */
+
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.default:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.cpu_power6:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.cpu_power6x:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\tbl _Z3fooi\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi, 
@gnu_indirect_function\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.set\t_Z3fooi,_Z3fooi\.resolver\n" 
1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3fooi\.default\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3fooi\.cpu_power6\n" 0 } } 
*/
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3fooi\.cpu_power6x\n" 1 } 
} */
diff --git a/gcc/testsuite/g++.target/powerpc/mvc-symbols2.C 
b/gcc/testsuite/g++.target/powerpc/mvc-symbols2.C
new file mode 100644
index ..edf54480efd1
--- /dev/null
+++ b/gcc/testsuite/g++.target/powerpc/mvc-symbols2.C
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O0" } */
+
+__attribute__((target_clones("default", "cpu=power6", "cpu=power6x")))
+int foo ()
+{
+  return 1;
+}
+
+__attribute__((target_clones("cpu=power6x", "cpu=power6", "default")))
+int foo (int)
+{
+  return 2;
+}
+
+/* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.cpu_power6:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.cpu_power6x:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, 
@gnu_indirect_function\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 
1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3foov\.default\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3foov\.cpu_power6\n" 1 } } 
*/
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3foov\.cpu_power6x\n" 0 } 
} */
+
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.default:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.cpu_power6:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.cpu_power6x:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi, 
@gnu_indirect_function\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.set\t_Z3fooi,_Z3fooi\.resolver\n" 
1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.

[gcc(refs/users/alfierichards/heads/fmv_c)] Change function versions to be implicitly ordered.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:ef26faa3ebf69727e6f73b430d935e390f9cb577

commit ef26faa3ebf69727e6f73b430d935e390f9cb577
Author: Alfie Richards 
Date:   Thu Mar 27 14:12:06 2025 +

Change function versions to be implicitly ordered.

This changes function version structures to maintain the default version
as the first declaration in the linked data structures by giving priority
to the set containing the default when constructing the structure.

This allows for removing logic for moving the default to the first
position which was duplicated across target specific code and enables
easier reasoning about function sets when checking for a default.

gcc/ChangeLog:

* cgraph.cc (cgraph_node::record_function_versions): Refactor and
rename to...
(cgraph_node::add_function_version): new function.
* cgraph.h (cgraph_node::record_function_versions): Refactor and
rename to...
(cgraph_node::add_function_version): new function.
* config/aarch64/aarch64.cc 
(aarch64_get_function_versions_dispatcher):
Remove reordering.
* config/i386/i386-features.cc 
(ix86_get_function_versions_dispatcher):
Remove reordering.
* config/riscv/riscv.cc (riscv_get_function_versions_dispatcher):
Remove reordering.
* config/rs6000/rs6000.cc (rs6000_get_function_versions_dispatcher):
Remove reordering.

gcc/cp/ChangeLog:

* decl.cc (maybe_version_functions): Change record_function_versions
call to add_function_version.

Diff:
---
 gcc/cgraph.cc| 50 ++--
 gcc/cgraph.h |  6 ++---
 gcc/config/aarch64/aarch64.cc| 37 +++--
 gcc/config/i386/i386-features.cc | 33 --
 gcc/config/riscv/riscv.cc| 38 +-
 gcc/config/rs6000/rs6000.cc  | 35 +---
 gcc/cp/decl.cc   |  8 ++-
 7 files changed, 63 insertions(+), 144 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 6ae6a97f6f56..a2ad2516c12b 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -231,43 +231,49 @@ cgraph_node::delete_function_version_by_decl (tree decl)
   decl_node->remove ();
 }
 
-/* Record that DECL1 and DECL2 are semantically identical function
-   versions.  */
+/* Add decl to the structure of semantically identical function versions..  */
 void
-cgraph_node::record_function_versions (tree decl1, tree decl2)
+cgraph_node::add_function_version (cgraph_function_version_info *fn_v,
+  tree decl)
 {
-  cgraph_node *decl1_node = cgraph_node::get_create (decl1);
-  cgraph_node *decl2_node = cgraph_node::get_create (decl2);
-  cgraph_function_version_info *decl1_v = NULL;
-  cgraph_function_version_info *decl2_v = NULL;
+  cgraph_node *decl_node = cgraph_node::get_create (decl);
+  cgraph_function_version_info *decl_v = NULL;
+
   cgraph_function_version_info *before;
   cgraph_function_version_info *after;
 
-  gcc_assert (decl1_node != NULL && decl2_node != NULL);
-  decl1_v = decl1_node->function_version ();
-  decl2_v = decl2_node->function_version ();
+  gcc_assert (decl_node != NULL);
+
+  decl_v = decl_node->function_version ();
 
-  if (decl1_v != NULL && decl2_v != NULL)
+  /* If the nodes are already linked, skip.  */
+  if (decl_v != NULL && (decl_v->next || decl_v->prev))
 return;
 
-  if (decl1_v == NULL)
-decl1_v = decl1_node->insert_new_function_version ();
+  if (decl_v == NULL)
+decl_v = decl_node->insert_new_function_version ();
 
-  if (decl2_v == NULL)
-decl2_v = decl2_node->insert_new_function_version ();
+  gcc_assert (decl_v);
+  gcc_assert (fn_v);
 
-  /* Chain decl2_v and decl1_v.  All semantically identical versions
- will be chained together.  */
+  before = fn_v;
+  after = decl_v;
 
-  before = decl1_v;
-  after = decl2_v;
+  /* Go to the beginning of both nodes (as after is on its own we just need to
+ this for before).  */
+  while (before->prev != NULL)
+before = before->prev;
 
+  /* Potentially swap the nodes to maintain the default always being in the
+ first position.  */
+  if (is_function_default_version (decl))
+std::swap (before, after);
+
+  /* Go to last node of before.  */
   while (before->next != NULL)
 before = before->next;
 
-  while (after->prev != NULL)
-after= after->prev;
-
+  /* Chain decl2_v and decl1_v.  */
   before->next = after;
   after->prev = before;
 }
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 065fcc742e8b..6759505bf338 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1319,9 +1319,9 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : 
public symtab_node
 return m_summary_id;
   }
 
-  /* Record that DECL1 and DECL2 are semantically identical function
- versions.  */
-  static void record_f

[gcc(refs/users/alfierichards/heads/fmv_c)] Add string_slice class.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:aa80e36976e1a5d6e51bcad77ccb27fcd6e31874

commit aa80e36976e1a5d6e51bcad77ccb27fcd6e31874
Author: Alfie Richards 
Date:   Mon Mar 24 10:45:56 2025 +

Add string_slice class.

The string_slice inherits from array_slice and is used to refer to a
substring of an array that is memory managed elsewhere without modifying
the underlying array.

For example, this is useful in cases such as when needing to refer to a
substring of an attribute in the syntax tree.

This commit also adds some minimal helper functions for string_slice,
such as a strtok alternative, equality operators, strcmp, and a function
to strip whitespace from the beginning and end of a string_slice.

gcc/c-family/ChangeLog:

* c-format.cc (local_string_slice_node): New node type.
(asm_fprintf_char_table): New entry.
(init_dynamic_diag_info): Add support for string_slice.
* c-format.h (T_STRING_SLICE): New node type.

gcc/ChangeLog:

* pretty-print.cc (format_phase_2): Add support for string_slice.
* vec.cc (string_slice::tokenize): New method.
(strcmp): New implementation for string_slice.
(string_slice::strip): New method.
(test_string_slice_initializers): New test.
(test_string_slice_tokenize): Ditto.
(test_string_slice_strcmp): Ditto.
(test_string_slice_equality): Ditto.
(test_string_slice_inequality): Ditto.
(test_string_slice_invalid): Ditto.
(test_string_slice_strip): Ditto.
(vec_cc_tests): Add new tests.
* vec.h (class string_slice): New class.
(strcmp): New implementation for stirng_slice.

Diff:
---
 gcc/c-family/c-format.cc |   9 +++
 gcc/c-family/c-format.h  |   1 +
 gcc/pretty-print.cc  |  10 +++
 gcc/vec.cc   | 207 +++
 gcc/vec.h|  45 +++
 5 files changed, 272 insertions(+)

diff --git a/gcc/c-family/c-format.cc b/gcc/c-family/c-format.cc
index 211d20dd25bf..8b4447f9fdc8 100644
--- a/gcc/c-family/c-format.cc
+++ b/gcc/c-family/c-format.cc
@@ -70,6 +70,7 @@ static GTY(()) tree local_event_ptr_node;
 static GTY(()) tree local_pp_element_ptr_node;
 static GTY(()) tree local_gimple_ptr_node;
 static GTY(()) tree local_cgraph_node_ptr_node;
+static GTY(()) tree local_string_slice_node;
 static GTY(()) tree locus;
 
 static bool decode_format_attr (const_tree, tree, tree, function_format_info *,
@@ -770,6 +771,7 @@ static const format_char_info asm_fprintf_char_table[] =
   { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "c",  NULL }, \
   { "r",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "","//cR",   NULL 
}, \
   { "@",   1, STD_C89, { T_EVENT_PTR,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "\"",   NULL }, \
+  { "B",   1, STD_C89, { T_STRING_SLICE,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q", "",   NULL }, \
   { "e",   1, STD_C89, { T_PP_ELEMENT_PTR,   BADLEN,  BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "\"", NULL }, \
   { "<",   0, STD_C89, NOARGUMENTS, "",  "<",   NULL }, \
   { ">",   0, STD_C89, NOARGUMENTS, "",  ">",   NULL }, \
@@ -5211,6 +5213,13 @@ init_dynamic_diag_info (void)
   || local_cgraph_node_ptr_node == void_type_node)
 local_cgraph_node_ptr_node = get_named_type ("cgraph_node");
 
+  /* Similar to the above but for string_slice*.  */
+  if (!local_string_slice_node
+  || local_string_slice_node == void_type_node)
+{
+  local_string_slice_node = get_named_type ("string_slice");
+}
+
   /* Similar to the above but for diagnostic_event_id_t*.  */
   if (!local_event_ptr_node
   || local_event_ptr_node == void_type_node)
diff --git a/gcc/c-family/c-format.h b/gcc/c-family/c-format.h
index 323338cb8e7f..d44d3862d830 100644
--- a/gcc/c-family/c-format.h
+++ b/gcc/c-family/c-format.h
@@ -317,6 +317,7 @@ struct format_kind_info
 #define T89_G   { STD_C89, NULL, &local_gimple_ptr_node }
 #define T_CGRAPH_NODE   { STD_C89, NULL, &local_cgraph_node_ptr_node }
 #define T_EVENT_PTR{ STD_C89, NULL, &local_event_ptr_node }
+#define T_STRING_SLICE{ STD_C89, NULL, &local_string_slice_node }
 #define T_PP_ELEMENT_PTR{ STD_C89, NULL, &local_pp_element_ptr_node }
 #define T89_T   { STD_C89, NULL, &local_tree_type_node }
 #define T89_V  { STD_C89, NULL, T_V }
diff --git a/gcc/pretty-print.cc b/gcc/pretty-print.cc
index 79c7bc2b6625..280cde30adcb 100644
--- a/gcc/pretty-print.cc
+++ b/gcc/pretty-print.cc
@@ -2035,6 +2035,16 @@ format_phase_2 (pretty_printer *pp,
pp_string (pp, va_arg (*text.m_args_ptr, const cha

[gcc(refs/users/alfierichards/heads/fmv_c)] Add dispatcher_resolver_function and is_target_clone to cgraph_node.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:4936254aa6111db3e85e07da4894b6950a7d1b76

commit 4936254aa6111db3e85e07da4894b6950a7d1b76
Author: Alfie Richards 
Date:   Fri Jan 31 11:46:08 2025 +

Add dispatcher_resolver_function and is_target_clone to cgraph_node.

These flags are used to make sure mangling is done correctly.

gcc/ChangeLog:

* cgraph.h (struct cgraph_node): Add dispatcher_resolver_function 
and
is_target_clone.

Diff:
---
 gcc/cgraph.h | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 4a4fb7302b19..91e5de30f98c 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -907,7 +907,9 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public 
symtab_node
   used_as_abstract_origin (false),
   lowered (false), process (false), frequency (NODE_FREQUENCY_NORMAL),
   only_called_at_startup (false), only_called_at_exit (false),
-  tm_clone (false), dispatcher_function (false), calls_comdat_local 
(false),
+  tm_clone (false), dispatcher_function (false),
+  dispatcher_resolver_function (false), is_target_clone (false),
+  calls_comdat_local (false),
   icf_merged (false), nonfreeing_fn (false), merged_comdat (false),
   merged_extern_inline (false), parallelized_function (false),
   split_part (false), indirect_call_target (false), local (false),
@@ -1465,6 +1467,11 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : 
public symtab_node
   unsigned tm_clone : 1;
   /* True if this decl is a dispatcher for function versions.  */
   unsigned dispatcher_function : 1;
+  /* True if this decl is a resolver for function versions.  */
+  unsigned dispatcher_resolver_function : 1;
+  /* True this is part of a multiversioned set and the default version
+ comes from a target_clone attribute.  */
+  unsigned is_target_clone : 1;
   /* True if this decl calls a COMDAT-local function.  This is set up in
  compute_fn_summary and inline_call.  */
   unsigned calls_comdat_local : 1;


[gcc(refs/users/alfierichards/heads/fmv_c)] Add assembler_name to cgraph_function_version_info.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:376346bceddbd874cb7a0c02fbe2feb77cecdce5

commit 376346bceddbd874cb7a0c02fbe2feb77cecdce5
Author: Alfie Richards 
Date:   Wed Feb 5 12:56:52 2025 +

Add assembler_name to cgraph_function_version_info.

This adds the assembler_name member to cgraph_function_version_info
to store the base assembler name for the function to be mangled. This is
used in later patches for refactoring FMV mangling.

gcc/ChangeLog:

* cgraph.cc (cgraph_node::insert_new_function_version): Record
assembler_name.
* cgraph.h (struct cgraph_function_version_info): Add 
assembler_name.

Diff:
---
 gcc/cgraph.cc | 1 +
 gcc/cgraph.h  | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index a2ad2516c12b..e81c7262d36a 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -187,6 +187,7 @@ cgraph_node::insert_new_function_version (void)
   version_info_node = NULL;
   version_info_node = ggc_cleared_alloc ();
   version_info_node->this_node = this;
+  version_info_node->assembler_name = DECL_ASSEMBLER_NAME (this->decl);
 
   if (cgraph_fnver_htab == NULL)
 cgraph_fnver_htab = hash_table::create_ggc (2);
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 6759505bf338..4a4fb7302b19 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -856,6 +856,9 @@ struct GTY((for_user)) cgraph_function_version_info {
  dispatcher. The dispatcher decl is an alias to the resolver
  function decl.  */
   tree dispatcher_resolver;
+
+  /* The assmbly name of the function set before version mangling.  */
+  tree assembler_name;
 };
 
 #define DEFCIFCODE(code, type, string) CIF_ ## code,


[gcc(refs/users/alfierichards/heads/fmv_c)] Remove unnecessary `record` argument from maybe_version_functions.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:5cb80d373a338aec848850d90d12063ff5a704f9

commit 5cb80d373a338aec848850d90d12063ff5a704f9
Author: Alfie Richards 
Date:   Tue Jan 28 15:42:49 2025 +

Remove unnecessary `record` argument from maybe_version_functions.

Previously, the `record` argument in maybe_version_function allowed the
call to cgraph_node::record_function_versions to be skipped.  However,
this was only skipped when both decls were already marked as versioned,
in which case we trigger the early exit in record_function_versions
instead. Therefore, the argument is unnecessary.

gcc/cp/ChangeLog:

* class.cc (add_method): Remove argument.
* cp-tree.h (maybe_version_functions): Ditto.
* decl.cc (decls_match): Ditto.
(maybe_version_functions): Ditto.

Diff:
---
 gcc/cp/class.cc  | 2 +-
 gcc/cp/cp-tree.h | 2 +-
 gcc/cp/decl.cc   | 9 +++--
 3 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index 2b694b98e565..93f1a1bdd81b 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -1402,7 +1402,7 @@ add_method (tree type, tree method, bool via_using)
   /* If these are versions of the same function, process and
 move on.  */
   if (TREE_CODE (fn) == FUNCTION_DECL
- && maybe_version_functions (method, fn, true))
+ && maybe_version_functions (method, fn))
continue;
 
   if (DECL_INHERITED_CTOR (method))
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 927f51b116b3..5bfc08191f6d 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7122,7 +7122,7 @@ extern void determine_local_discriminator (tree, tree = 
NULL_TREE);
 extern bool member_like_constrained_friend_p   (tree);
 extern bool fns_correspond (tree, tree);
 extern int decls_match (tree, tree, bool = true);
-extern bool maybe_version_functions(tree, tree, bool);
+extern bool maybe_version_functions(tree, tree);
 extern bool validate_constexpr_redeclaration   (tree, tree);
 extern bool merge_default_template_args(tree, tree, bool);
 extern tree duplicate_decls(tree, tree,
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 2ed94fd786ce..85c1b63c1f54 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -1216,9 +1216,7 @@ decls_match (tree newdecl, tree olddecl, bool 
record_versions /* = true */)
  && targetm.target_option.function_versions (newdecl, olddecl))
{
  if (record_versions)
-   maybe_version_functions (newdecl, olddecl,
-(!DECL_FUNCTION_VERSIONED (newdecl)
- || !DECL_FUNCTION_VERSIONED (olddecl)));
+   maybe_version_functions (newdecl, olddecl);
  return 0;
}
 }
@@ -1289,7 +1287,7 @@ maybe_mark_function_versioned (tree decl)
If RECORD is set to true, record function versions.  */
 
 bool
-maybe_version_functions (tree newdecl, tree olddecl, bool record)
+maybe_version_functions (tree newdecl, tree olddecl)
 {
   if (!targetm.target_option.function_versions (newdecl, olddecl))
 return false;
@@ -1312,8 +1310,7 @@ maybe_version_functions (tree newdecl, tree olddecl, bool 
record)
   maybe_mark_function_versioned (newdecl);
 }
 
-  if (record)
-cgraph_node::record_function_versions (olddecl, newdecl);
+  cgraph_node::record_function_versions (olddecl, newdecl);
 
   return true;
 }


[gcc(refs/users/alfierichards/heads/fmv_c)] Change make_attribute to take string_slice.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:591e01d35957ab3e2a8082e0f2ef6e855683aa16

commit 591e01d35957ab3e2a8082e0f2ef6e855683aa16
Author: Alfie Richards 
Date:   Fri Jan 31 10:49:42 2025 +

Change make_attribute to take string_slice.

gcc/ChangeLog:

* attribs.cc (make_attribute): Change arguments.
* attribs.h (make_attribute): Change arguments.

Diff:
---
 gcc/attribs.cc | 18 ++
 gcc/attribs.h  |  2 +-
 2 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index f6667839c013..37d6ce0f9161 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -1072,25 +1072,19 @@ apply_tm_attr (tree fndecl, tree attr)
   decl_attributes (&TREE_TYPE (fndecl), tree_cons (attr, NULL, NULL), 0);
 }
 
-/* Makes a function attribute of the form NAME(ARG_NAME) and chains
+/* Makes a function attribute of the form NAME (ARG_NAME) and chains
it to CHAIN.  */
 
 tree
-make_attribute (const char *name, const char *arg_name, tree chain)
+make_attribute (string_slice name, string_slice arg_name, tree chain)
 {
-  tree attr_name;
-  tree attr_arg_name;
-  tree attr_args;
-  tree attr;
-
-  attr_name = get_identifier (name);
-  attr_arg_name = build_string (strlen (arg_name), arg_name);
-  attr_args = tree_cons (NULL_TREE, attr_arg_name, NULL_TREE);
-  attr = tree_cons (attr_name, attr_args, chain);
+  tree attr_name = get_identifier_with_length (name.begin (), name.size ());
+  tree attr_arg_name = build_string (arg_name.size (), arg_name.begin ());
+  tree attr_args = tree_cons (NULL_TREE, attr_arg_name, NULL_TREE);
+  tree attr = tree_cons (attr_name, attr_args, chain);
   return attr;
 }
 
-
 /* Common functions used for target clone support.  */
 
 /* Comparator function to be used in qsort routine to sort attribute
diff --git a/gcc/attribs.h b/gcc/attribs.h
index 4b946390f76b..b8b6838599cc 100644
--- a/gcc/attribs.h
+++ b/gcc/attribs.h
@@ -45,7 +45,7 @@ extern bool cxx11_attribute_p (const_tree);
 extern tree get_attribute_name (const_tree);
 extern tree get_attribute_namespace (const_tree);
 extern void apply_tm_attr (tree, tree);
-extern tree make_attribute (const char *, const char *, tree);
+extern tree make_attribute (string_slice, string_slice, tree);
 extern bool attribute_ignored_p (tree);
 extern bool attribute_ignored_p (const attribute_spec *const);
 extern bool any_nonignored_attribute_p (tree);


[gcc(refs/users/alfierichards/heads/fmv_c)] Refactor FMV frontend hooks and logic.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:564bd7c0b472d5ce1d112c6111dedc1a480bb3f1

commit 564bd7c0b472d5ce1d112c6111dedc1a480bb3f1
Author: Alfie Richards 
Date:   Mon Mar 24 13:20:01 2025 +

Refactor FMV frontend hooks and logic.

This change refactors FMV handling in the frontend to allows greater
reasoning about versions in shared code.

This is needed for target_version semantics and allowing target_clones
and target_versions to both be used for the declaration there are now
two questions that need to be answered for the front end.

1. Are these two declarations completely distinct FMV declarations
(ie. the versions they define have no overlap). If so, they don't match.
2. Are these two declarations matching and therefore mergeable.
(ie. two target_clone decls that define the same set of versions, or
an un-annotated declaration, and a target_clones definition containing the
default version). If so, the existing merging logic should be used to
try to merge these and diagnose if it's not possible. If not, then this
needs to be diagnosed.

To do this the common_function_versions function has been renamed
distinct_function_versions (meaning, are the versions defined by these
two functions completely distinct from eachother).

The common function version hook was changed to instead take two
string_slice's and determine if they define the same version.

There is a new function, called mergeable_version_decls which checks
if two decls (which define overlapping versions) can be merged.
For example, if they are two target_clone decls which define the exact
same set of versions.

This change also records the conflicting version so that it can be
included in diagnostics.

gcc/ChangeLog:

* attribs.cc (attr_strcmp): Moved to target specific code.
(sorted_attr_string): Moved to target specific code.
(common_function_versions): New function.
* attribs.h (sorted_attr_string): Removed.
(common_function_versions): New function.
* config/aarch64/aarch64.cc (aarch64_common_function_versions):
New function.
* config/riscv/riscv.cc (riscv_common_function_versions): New 
function.
* doc/tm.texi: Regenerated.
* target.def: Change common_function_versions hook.
* tree.cc (distinct_version_decls): New function.
(mergeable_version_decls): Ditto.
* tree.h (distinct_version_decls): New function.
(mergeable_version_decls): Ditto.

gcc/cp/ChangeLog:

* class.cc (resolve_address_of_overloaded_function): Updated to use
distinct_version_decls instead of common_function_version hook.
* cp-tree.h (decls_match): Updated to use
distinct_version_decls instead of common_function_version hook.
* decl.cc (decls_match): Refacture to use distinct_version_decls and
to pass through conflicting_version argument.
(maybe_version_functions): Updated to use
distinct_version_decls instead of common_function_version hook.
(duplicate_decls): Add logic to handle conflicting unmergable decls
and improve diagnostics for conflicting versions.
* decl2.cc (check_classfn): Updated to use
distinct_version_decls instead of common_function_version hook.

Diff:
---
 gcc/attribs.cc|  75 ++--
 gcc/attribs.h |   3 +-
 gcc/config/aarch64/aarch64.cc |  16 ++--
 gcc/config/riscv/riscv.cc |  30 ---
 gcc/cp/class.cc   |   4 +-
 gcc/cp/cp-tree.h  |   2 +-
 gcc/cp/decl.cc|  43 +++--
 gcc/cp/decl2.cc   |   2 +-
 gcc/doc/tm.texi   |   4 +-
 gcc/target.def|   6 +-
 gcc/tree.cc   | 204 ++
 gcc/tree.h|   6 ++
 12 files changed, 291 insertions(+), 104 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 80833388ff2e..04a9e743dbe0 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -1086,7 +1086,14 @@ make_attribute (string_slice name, string_slice 
arg_name, tree chain)
   return attr;
 }
 
-/* Common functions used for target clone support.  */
+/* Used for targets with target_version semantics.  */
+
+bool
+common_function_versions (string_slice fn1 ATTRIBUTE_UNUSED,
+ string_slice fn2 ATTRIBUTE_UNUSED)
+{
+  gcc_unreachable ();
+}
 
 /* Comparator function to be used in qsort routine to sort attribute
specification strings to "target".  */
@@ -1176,72 +1183,6 @@ sorted_attr_string (tree arglist)
   XDELETEVEC (attr_str);
   return ret_str;
 }
-
-
-/* This function returns true if FN1 and FN2 are versions of the same function,
-   that is, the target strings of the function decls are differen

[gcc(refs/users/alfierichards/heads/fmv_c)] Add error cases and tests for Aarch64 FMV.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:f54b7da000f2d3fe1211957fb2e33a87882461cc

commit f54b7da000f2d3fe1211957fb2e33a87882461cc
Author: Alfie Richards 
Date:   Thu Feb 13 15:59:43 2025 +

Add error cases and tests for Aarch64 FMV.

This changes the ambiguation error for C++ to cover cases of differently
annotated FMV function sets whose signatures only differ by their return
type.

It also adds tests covering many FMV errors for Aarch64, including
redeclaration, and mixing target_clones and target_versions.

gcc/cp/ChangeLog:
PR c++/119498
* decl.cc (duplicate_decls): Change logic to not always exclude FMV
annotated functions in cases of return type non-ambiguation.

gcc/testsuite/ChangeLog:

* g++.target/aarch64/mv-and-mvc-error1.C: New test.
* g++.target/aarch64/mv-and-mvc-error2.C: New test.
* g++.target/aarch64/mv-and-mvc-error3.C: New test.
* g++.target/aarch64/mv-error1.C: New test.
* g++.target/aarch64/mv-error2.C: New test.
* g++.target/aarch64/mv-error3.C: New test.
* g++.target/aarch64/mv-error4.C: New test.
* g++.target/aarch64/mv-error5.C: New test.
* g++.target/aarch64/mv-error6.C: New test.
* g++.target/aarch64/mv-error7.C: New test.
* g++.target/aarch64/mv-error8.C: New test.
* g++.target/aarch64/mvc-error1.C: New test.
* g++.target/aarch64/mvc-error2.C: New test.
* g++.target/aarch64/mvc-warning1.C: Modified test.

Diff:
---
 gcc/cp/decl.cc  |  7 +--
 .../g++.target/aarch64/mv-and-mvc-error1.C  | 10 ++
 .../g++.target/aarch64/mv-and-mvc-error2.C  | 10 ++
 .../g++.target/aarch64/mv-and-mvc-error3.C  |  9 +
 gcc/testsuite/g++.target/aarch64/mv-error1.C| 19 +++
 gcc/testsuite/g++.target/aarch64/mv-error2.C| 10 ++
 gcc/testsuite/g++.target/aarch64/mv-error3.C| 13 +
 gcc/testsuite/g++.target/aarch64/mv-error4.C| 10 ++
 gcc/testsuite/g++.target/aarch64/mv-error5.C|  9 +
 gcc/testsuite/g++.target/aarch64/mv-error6.C| 21 +
 gcc/testsuite/g++.target/aarch64/mv-error7.C| 12 
 gcc/testsuite/g++.target/aarch64/mv-error8.C| 13 +
 gcc/testsuite/g++.target/aarch64/mvc-error1.C   | 10 ++
 gcc/testsuite/g++.target/aarch64/mvc-error2.C   | 10 ++
 gcc/testsuite/g++.target/aarch64/mvc-warning1.C | 12 ++--
 15 files changed, 171 insertions(+), 4 deletions(-)

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index c53a8ac4567a..c20af9bc322a 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -2022,8 +2022,11 @@ duplicate_decls (tree newdecl, tree olddecl, bool 
hiding, bool was_hidden)
}
  /* For function versions, params and types match, but they
 are not ambiguous.  */
- else if ((!DECL_FUNCTION_VERSIONED (newdecl)
-   && !DECL_FUNCTION_VERSIONED (olddecl))
+ else if (((!DECL_FUNCTION_VERSIONED (newdecl)
+&& !DECL_FUNCTION_VERSIONED (olddecl))
+   || !comptypes (TREE_TYPE (TREE_TYPE (newdecl)),
+  TREE_TYPE (TREE_TYPE (olddecl)),
+  COMPARE_STRICT))
   /* Let constrained hidden friends coexist for now, we'll
  check satisfaction later.  */
   && !member_like_constrained_friend_p (newdecl)
diff --git a/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error1.C 
b/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error1.C
new file mode 100644
index ..00d3826f757f
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error1.C
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O0" } */
+/* { dg-additional-options "-Wno-experimental-fmv-target" } */
+
+__attribute__ ((target_version ("dotprod"))) int
+foo () { return 3; } /* { dg-message "previous definition" } */
+
+__attribute__ ((target_clones ("dotprod", "sve"))) int
+foo () { return 1; } /* { dg-error "conflicting .dotprod. versions" } */
diff --git a/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error2.C 
b/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error2.C
new file mode 100644
index ..bf8a4112a216
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error2.C
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O0" } */
+/* { dg-additional-options "-Wno-experimental-fmv-target" } */
+
+__attribute__ ((target_version ("default"))) int
+foo () { return 1; } /* { dg-message "old declaration" } */
+
+__attribute__ ((target_clones ("dotprod", "sve"))) float
+foo () { return 3; } /* { dg-error "ambiguating new declaration of" } 

[gcc(refs/users/alfierichards/heads/fmv_c)] Refactor riscv target parsing to take string_slice.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:1c497dd6c089b53e388f847807029348b3620bc3

commit 1c497dd6c089b53e388f847807029348b3620bc3
Author: Alfie Richards 
Date:   Mon Mar 24 11:45:32 2025 +

Refactor riscv target parsing to take string_slice.

This is a quick refactor of the riscv target processing code
to take a string_slice rather than a decl.

The reason for this is to enable it to work with target_clones
where merging logic requires reasoning about each version string
individually in the front end.

This refactor primarily serves just to get this working. Ideally the
logic here would be further refactored as currenly there is no way to
check if a parse fails or not without emitting an error.
This makes things difficult for later patches which intends to emit a
warning and ignoring unrecognised/not parsed target_clone values rather
than erroring which can't currenly be achieved with the current riscv
code.

gcc/ChangeLog:

* config/riscv/riscv-protos.h (riscv_process_target_version_str): 
New function..
* config/riscv/riscv-target-attr.cc (riscv_process_target_attr): 
Refactor to take
string_slice.
(riscv_process_target_version_str): Ditto.
* config/riscv/riscv.cc (parse_features_for_version): Refactor to 
take
string_slice.
(riscv_compare_version_priority): Ditto.
(dispatch_function_versions): Change to pass location.

Diff:
---
 gcc/config/riscv/riscv-protos.h   |  2 ++
 gcc/config/riscv/riscv-target-attr.cc | 14 ++
 gcc/config/riscv/riscv.cc | 50 ++-
 3 files changed, 37 insertions(+), 29 deletions(-)

diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 2bedd878a04e..1efe45d63e6f 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -813,6 +813,8 @@ riscv_option_valid_attribute_p (tree, tree, tree, int);
 extern bool
 riscv_option_valid_version_attribute_p (tree, tree, tree, int);
 extern bool
+riscv_process_target_version_str (string_slice, location_t);
+extern bool
 riscv_process_target_version_attr (tree, location_t);
 extern void
 riscv_override_options_internal (struct gcc_options *);
diff --git a/gcc/config/riscv/riscv-target-attr.cc 
b/gcc/config/riscv/riscv-target-attr.cc
index 1d968655f95d..d3f06fb15d42 100644
--- a/gcc/config/riscv/riscv-target-attr.cc
+++ b/gcc/config/riscv/riscv-target-attr.cc
@@ -354,11 +354,11 @@ num_occurrences_in_str (char c, char *str)
and update the global target options space.  */
 
 bool
-riscv_process_target_attr (const char *args,
+riscv_process_target_attr (string_slice args,
   location_t loc,
   const struct riscv_attribute_info *attrs)
 {
-  size_t len = strlen (args);
+  size_t len = args.size ();
 
   /* No need to emit warning or error on empty string here, generic code 
already
  handle this case.  */
@@ -369,7 +369,7 @@ riscv_process_target_attr (const char *args,
 
   std::unique_ptr buf (new char[len+1]);
   char *str_to_check = buf.get ();
-  strcpy (str_to_check, args);
+  strncpy (str_to_check, args.begin (), args.size ());
 
   /* Used to catch empty spaces between semi-colons i.e.
  attribute ((target ("attr1;;attr2"))).  */
@@ -391,8 +391,7 @@ riscv_process_target_attr (const char *args,
 
   if (num_attrs != num_semicolons + 1)
 {
-  error_at (loc, "malformed % attribute",
-   args);
+  error_at (loc, "malformed % attribute", &args);
   return false;
 }
 
@@ -513,6 +512,11 @@ riscv_process_target_version_attr (tree args, location_t 
loc)
   return riscv_process_target_attr (str, loc, riscv_target_version_attrs);
 }
 
+bool
+riscv_process_target_version_str (string_slice str, location_t loc)
+{
+  return riscv_process_target_attr (str, loc, riscv_target_version_attrs);
+}
 
 /* Implement TARGET_OPTION_VALID_VERSION_ATTRIBUTE_P.  This is used to
process attribute ((target_version ("..."))).  */
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index baf2ea778210..723f8c1ebce6 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -13092,31 +13092,22 @@ riscv_c_mode_for_floating_type (enum tree_index ti)
   return default_mode_for_floating_type (ti);
 }
 
-/* This parses the attribute arguments to target_version in DECL and modifies
-   the feature mask and priority required to select those targets.  */
-static void
-parse_features_for_version (tree decl,
+/* This parses STR and modifies the feature mask and priority required to
+   select those targets.  */
+static bool
+parse_features_for_version (string_slice version_str,
+   location_t loc,
struct riscv_feature_bits &res,
int &priority)
 {
-  tree version_attr = lookup_attribute ("target_version",
-  

[gcc(refs/users/alfierichards/heads/fmv_c)] Add reject_target_clone hook in order to filter target_clone versions.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:f5e08ff26e1a5e6f2799f5828008eeec1edddc5d

commit f5e08ff26e1a5e6f2799f5828008eeec1edddc5d
Author: Alfie Richards 
Date:   Mon Mar 24 15:04:38 2025 +

Add reject_target_clone hook in order to filter target_clone versions.

This patch introduces the TARGET_REJECT_FUNCTION_CLONE_VERSION hook
which is used to determine if a target_clones version string parses.

If true is returned, a warning is emitted and from then on the version
is ignored.

This is as specified in the Arm C Language Extension. The purpose of this
is to allow some portability of code using target_clones attributes.

Currently this is only properly implemented for the Aarch64 backend.

For riscv which is the only other backend which uses target_version
semantics a partial implementation is present, where this hook is used
to check parsing, in which errors will be emitted on a failed parse
rather than warnings. A refactor of the riscv parsing logic would be
required to enable this functionality fully.

Additionally, after refactoring the riscv logic, the location argument
to the hook would be unnecessary.

This also fixes PR 118339 where parse failures could cause ICE in Aarch64.

gcc/ChangeLog:

PR target/118339
* attribs.cc (reject_target_clone_version): New function.
* target.def: Add reject_target_clone_version hook.
* tree.cc (get_clone_attr_versions): Add filter and location 
argument.
(get_clone_versions): Update call to get_clone_attr_versions.
* tree.h (get_clone_attr_versions): Add filter and location 
argument.
* config/aarch64/aarch64.cc (aarch64_reject_target_clone_version):
New function
(TARGET_REJECT_FUNCTION_CLONE_VERSION):
New define.
* config/i386/i386.cc (TARGET_REJECT_FUNCTION_CLONE_VERSION):
New define.
* config/riscv/riscv.cc (riscv_reject_target_clone_version):
New function.
(TARGET_REJECT_FUNCTION_CLONE_VERSION):
New define.
* config/rs6000/rs6000.cc (TARGET_REJECT_FUNCTION_CLONE_VERSION):
New define.
* doc/tm.texi: Regenerated.
* doc/tm.texi.in: Add documentation for new hook.

gcc/c-family/ChangeLog:

* c-attribs.cc (handle_target_clones_attribute): Update to emit 
warnings
for rejected versions.

Diff:
---
 gcc/attribs.cc|  7 +++
 gcc/c-family/c-attribs.cc | 26 +-
 gcc/config/aarch64/aarch64.cc | 20 
 gcc/config/i386/i386.cc   |  3 +++
 gcc/config/riscv/riscv.cc | 18 ++
 gcc/config/rs6000/rs6000.cc   |  3 +++
 gcc/doc/tm.texi   |  5 +
 gcc/doc/tm.texi.in|  2 ++
 gcc/target.def|  8 
 gcc/tree.cc   | 12 ++--
 gcc/tree.h|  8 ++--
 11 files changed, 103 insertions(+), 9 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 09c4db96531d..80833388ff2e 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -1242,6 +1242,13 @@ common_function_versions (tree fn1, tree fn2)
   return result;
 }
 
+bool
+reject_target_clone_version (string_slice str ATTRIBUTE_UNUSED,
+location_t loc ATTRIBUTE_UNUSED)
+{
+  return false;
+}
+
 /* Make a dispatcher declaration for the multi-versioned function DECL.
Calls to DECL function will be replaced with calls to the dispatcher
by the front-end.  Return the decl created.  */
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 5dff489fccae..b5287f0da06d 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -6132,12 +6132,28 @@ handle_target_clones_attribute (tree *node, tree name, 
tree ARG_UNUSED (args),
}
}
 
-  auto_vec versions= get_clone_attr_versions (args, NULL);
-
-  if (versions.length () == 1)
-   {
+  int num_defaults = 0;
+  auto_vec versions= get_clone_attr_versions (args,
+ &num_defaults,
+ DECL_SOURCE_LOCATION (*node),
+ false);
+
+  for (auto v : versions)
+   if (targetm.reject_function_clone_version
+ (v, DECL_SOURCE_LOCATION (*node)))
  warning (OPT_Wattributes,
-  "single % attribute is ignored");
+  "invalid % version %qB ignored",
+  &v);
+
+  /* Lone target_clones version is always ignored for target attr 
semantics.
+Only ignore under target_version semantics if it is a default
+version.  */
+  if (versions.length () == 1 && (TARGET_HAS_FMV_TARGET_ATTRIBUTE
+ || num_defaults == 1))
+   {
+ if (TARGET_HAS_FMV_

[gcc(refs/users/alfierichards/heads/fmv_c)] Support mixing of target_clones and target_version.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:fd372533f3130f3dd554d5afb05fed9bbe61c8f1

commit fd372533f3130f3dd554d5afb05fed9bbe61c8f1
Author: Alfie Richards 
Date:   Mon Mar 24 16:02:07 2025 +

Support mixing of target_clones and target_version.

This patch adds support for the combination of target_clones and
target_version in the definition of a versioned function.

This patch changes is_function_default_version to consider a function
declaration annotated with target_clones containing default to be a
default version.

This takes advantage of refactoring done in previous patches changing
how target_clones are expanded and how conflicting decls are handled.

gcc/ChangeLog:

* attribs.cc (is_function_default_version): Update to handle
target_clones.
* cgraph.h (FOR_EACH_FUNCTION_REMOVABLE): New macro.
* multiple_target.cc (expand_target_clones): Update logic to delete
empty target_clones and modify diagnostic.
(ipa_target_clone): Update to use
FOR_EACH_FUNCTION_REMOVABLE.

gcc/c-family/ChangeLog:

* c-attribs.cc: Add support for target_version and target_clone 
mixing.

gcc/testsuite/ChangeLog:

* g++.target/aarch64/mv-and-mvc1.C: New test.
* g++.target/aarch64/mv-and-mvc2.C: New test.
* g++.target/aarch64/mv-and-mvc3.C: New test.
* g++.target/aarch64/mv-and-mvc4.C: New test.

Diff:
---
 gcc/attribs.cc | 10 ++-
 gcc/c-family/c-attribs.cc  |  9 +-
 gcc/cgraph.h   |  7 +
 gcc/multiple_target.cc | 24 ---
 gcc/testsuite/g++.target/aarch64/mv-and-mvc1.C | 38 
 gcc/testsuite/g++.target/aarch64/mv-and-mvc2.C | 29 ++
 gcc/testsuite/g++.target/aarch64/mv-and-mvc3.C | 41 ++
 gcc/testsuite/g++.target/aarch64/mv-and-mvc4.C | 38 
 8 files changed, 183 insertions(+), 13 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 04a9e743dbe0..57dd01531a3b 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -1247,7 +1247,8 @@ make_dispatcher_decl (const tree decl)
With the target attribute semantics, returns true if the function is marked
as default with the target version.
With the target_version attribute semantics, returns true if the function
-   is either not annotated, or annotated as default.  */
+   is either not annotated, annotated as default, or is a target_clone
+   containing the default declaration.  */
 
 bool
 is_function_default_version (const tree decl)
@@ -1264,6 +1265,13 @@ is_function_default_version (const tree decl)
 }
   else
 {
+  if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (decl)))
+   {
+ int num_defaults = 0;
+ get_clone_versions (decl, &num_defaults);
+ return num_defaults > 0;
+   }
+
   attr = lookup_attribute ("target_version", DECL_ATTRIBUTES (decl));
   if (!attr)
return true;
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index b5287f0da06d..a4e657d9ffd7 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -249,13 +249,6 @@ static const struct attribute_spec::exclusions 
attr_target_clones_exclusions[] =
   ATTR_EXCL ("always_inline", true, true, true),
   ATTR_EXCL ("target", TARGET_HAS_FMV_TARGET_ATTRIBUTE,
 TARGET_HAS_FMV_TARGET_ATTRIBUTE, TARGET_HAS_FMV_TARGET_ATTRIBUTE),
-  ATTR_EXCL ("target_version", true, true, true),
-  ATTR_EXCL (NULL, false, false, false),
-};
-
-static const struct attribute_spec::exclusions 
attr_target_version_exclusions[] =
-{
-  ATTR_EXCL ("target_clones", true, true, true),
   ATTR_EXCL (NULL, false, false, false),
 };
 
@@ -543,7 +536,7 @@ const struct attribute_spec c_common_gnu_attributes[] =
  attr_target_exclusions },
   { "target_version", 1, 1, true, false, false, false,
  handle_target_version_attribute,
- attr_target_version_exclusions },
+ NULL },
   { "target_clones",  1, -1, true, false, false, false,
  handle_target_clones_attribute,
  attr_target_clones_exclusions },
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 8dcc9315a51a..5a8ccb8042b0 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -3090,6 +3090,13 @@ symbol_table::next_function_with_gimple_body 
(cgraph_node *node)
for ((node) = symtab->first_function (); (node); \
(node) = symtab->next_function ((node)))
 
+/* Walk all functions but precompute so a node can be deleted if needed.  */
+#define FOR_EACH_FUNCTION_REMOVABLE(node) \
+   cgraph_node *next; \
+   for ((node) = symtab->first_function (), \
+   next = (node) ? symtab->next_

[gcc(refs/users/alfierichards/heads/fmv_c)] Add clone_identifier function.

2025-04-07 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:93a83a8e51a92699948ba322c22d071e89d0eedf

commit 93a83a8e51a92699948ba322c22d071e89d0eedf
Author: Alfie Richards 
Date:   Fri Jan 31 11:47:57 2025 +

Add clone_identifier function.

This is similar to clone_function_name and its siblings but takes an
identifier tree node rather than a function declaration.

This is to be used in conjunction with the identifier node stored in
cgraph_function_version_info::assembler_name to mangle FMV functions in
later patches.

gcc/ChangeLog:

* cgraph.h (clone_identifier): New function.
* cgraphclones.cc (clone_identifier): New function.
clone_function_name: Refactored to use clone_identifier.

Diff:
---
 gcc/cgraph.h|  1 +
 gcc/cgraphclones.cc | 16 ++--
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 91e5de30f98c..8dcc9315a51a 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -2629,6 +2629,7 @@ tree clone_function_name (const char *name, const char 
*suffix,
 tree clone_function_name (tree decl, const char *suffix,
  unsigned long number);
 tree clone_function_name (tree decl, const char *suffix);
+tree clone_identifier (tree decl, const char *suffix);
 
 void tree_function_versioning (tree, tree, vec *,
   ipa_param_adjustments *,
diff --git a/gcc/cgraphclones.cc b/gcc/cgraphclones.cc
index 5332a4333173..6b650849a63c 100644
--- a/gcc/cgraphclones.cc
+++ b/gcc/cgraphclones.cc
@@ -557,6 +557,14 @@ clone_function_name (tree decl, const char *suffix)
   /* For consistency this needs to behave the same way as
  ASM_FORMAT_PRIVATE_NAME does, but without the final number
  suffix.  */
+  return clone_identifier (identifier, suffix);
+}
+
+/* Return a new clone of ID ending with the string SUFFIX.  */
+
+tree
+clone_identifier (tree id, const char *suffix)
+{
   char *separator = XALLOCAVEC (char, 2);
   separator[0] = symbol_table::symbol_suffix_separator ();
   separator[1] = 0;
@@ -565,15 +573,11 @@ clone_function_name (tree decl, const char *suffix)
 #else
   const char *prefix = "";
 #endif
-  char *result = ACONCAT ((prefix,
-  IDENTIFIER_POINTER (identifier),
-  separator,
-  suffix,
-  (char*)0));
+  char *result = ACONCAT (
+(prefix, IDENTIFIER_POINTER (id), separator, suffix, (char *) 0));
   return get_identifier (result);
 }
 
-
 /* Create callgraph node clone with new declaration.  The actual body will be
copied later at compilation stage.  The name of the new clone will be
constructed from the name of the original node, SUFFIX and NUM_SUFFIX.


[gcc r14-11513] aarch64: Use PAUTH instead of V8_3A in some places

2025-04-02 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:35ed15af7ddab55c2ea1c07811f273a7c4e223fa

commit r14-11513-g35ed15af7ddab55c2ea1c07811f273a7c4e223fa
Author: Andrew Carlotti 
Date:   Tue Jul 30 16:26:04 2024 +0100

aarch64: Use PAUTH instead of V8_3A in some places

PR target/119383

gcc/ChangeLog:

* config/aarch64/aarch64.cc
(aarch64_expand_epilogue): Use TARGET_PAUTH.
* config/aarch64/aarch64.md: Update comment.

(cherry picked from commit 20385cb92cbd4a1934661ab97a162c1e25935836)

Diff:
---
 gcc/config/aarch64/aarch64.cc | 6 +++---
 gcc/config/aarch64/aarch64.md | 8 
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 0495adc7dd37..8f3a3735a97d 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -9995,12 +9995,12 @@ aarch64_expand_epilogue (rtx_call_insn *sibcall)
1) Sibcalls don't return in a normal way, so if we're about to call one
   we must authenticate.
 
-   2) The RETAA instruction is not available before ARMv8.3-A, so if we are
-  generating code for !TARGET_ARMV8_3 we can't use it and must
+   2) The RETAA instruction is not available without FEAT_PAuth, so if we
+  are generating code for !TARGET_PAUTH we can't use it and must
   explicitly authenticate.
 */
   if (aarch64_return_address_signing_enabled ()
-  && (sibcall || !TARGET_ARMV8_3))
+  && (sibcall || !TARGET_PAUTH))
 {
   switch (aarch64_ra_sign_key)
{
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index a08523a2b074..d3c381e82ce4 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -7627,11 +7627,11 @@
   [(set_attr "type" "f_cvtf2i")]
 )
 
-;; Pointer authentication patterns are always provided.  In architecture
-;; revisions prior to ARMv8.3-A these HINT instructions operate as NOPs.
+;; Pointer authentication patterns are always provided.  On targets that
+;; don't implement FEAT_PAuth these HINT instructions operate as NOPs.
 ;; This lets the user write portable software which authenticates pointers
-;; when run on something which implements ARMv8.3-A, and which runs
-;; correctly, but does not authenticate pointers, where ARMv8.3-A is not
+;; when run on something which implements FEAT_PAuth, and which runs
+;; correctly, but does not authenticate pointers, where FEAT_PAuth is not
 ;; implemented.
 
 ;; Signing/Authenticating R30 using SP as the salt.


[gcc r13-9482] aarch64: Use PAUTH instead of V8_3A in some places

2025-04-04 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:070296e6c313a7748efe053feacade4905901b5e

commit r13-9482-g070296e6c313a7748efe053feacade4905901b5e
Author: Andrew Carlotti 
Date:   Tue Jul 30 16:26:04 2024 +0100

aarch64: Use PAUTH instead of V8_3A in some places

gcc/ChangeLog:

* config/aarch64/aarch64.cc
(aarch64_expand_epilogue): Use TARGET_PAUTH.
* config/aarch64/aarch64.md: Update comment.

(cherry-picked from commit 20385cb92cbd4a1934661ab97a162c1e25935836)

Diff:
---
 gcc/config/aarch64/aarch64.cc | 6 +++---
 gcc/config/aarch64/aarch64.md | 8 
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 0a98f005b71c..b211f9abd60a 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -10363,12 +10363,12 @@ aarch64_expand_epilogue (bool for_sibcall)
1) Sibcalls don't return in a normal way, so if we're about to call one
   we must authenticate.
 
-   2) The RETAA instruction is not available before ARMv8.3-A, so if we are
-  generating code for !TARGET_ARMV8_3 we can't use it and must
+   2) The RETAA instruction is not available without FEAT_PAuth, so if we
+  are generating code for !TARGET_PAUTH we can't use it and must
   explicitly authenticate.
 */
   if (aarch64_return_address_signing_enabled ()
-  && (for_sibcall || !TARGET_ARMV8_3))
+  && (for_sibcall || !TARGET_PAUTH))
 {
   switch (aarch_ra_sign_key)
{
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index b585604cbe04..ff74e7dcef65 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -7280,11 +7280,11 @@
   [(set_attr "type" "f_cvtf2i")]
 )
 
-;; Pointer authentication patterns are always provided.  In architecture
-;; revisions prior to ARMv8.3-A these HINT instructions operate as NOPs.
+;; Pointer authentication patterns are always provided.  On targets that
+;; don't implement FEAT_PAuth these HINT instructions operate as NOPs.
 ;; This lets the user write portable software which authenticates pointers
-;; when run on something which implements ARMv8.3-A, and which runs
-;; correctly, but does not authenticate pointers, where ARMv8.3-A is not
+;; when run on something which implements FEAT_PAuth, and which runs
+;; correctly, but does not authenticate pointers, where FEAT_PAuth is not
 ;; implemented.
 
 ;; Signing/Authenticating R30 using SP as the salt.


[gcc(refs/users/alfierichards/heads/fmv_c)] Add get_clone_versions and get_version functions.

2025-04-10 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:17c466b660b798e22702e8ac5e3d6f840e1c6896

commit 17c466b660b798e22702e8ac5e3d6f840e1c6896
Author: Alfie Richards 
Date:   Fri Jan 31 10:51:14 2025 +

Add get_clone_versions and get_version functions.

This is a reimplementation of get_target_clone_attr_len,
get_attr_str, and separate_attrs using string_slice and auto_vec to make
memory management and use simpler.

This also adds get_version which is a helper function to get the version
string from a decl.

gcc/c-family/ChangeLog:

* c-attribs.cc (handle_target_clones_attribute): Change to use
get_clone_versions.

gcc/ChangeLog:

* tree.cc (get_clone_versions): New function.
(get_clone_attr_versions): New function.
(get_version): New function.
* tree.h (get_clone_versions): New function.
(get_clone_attr_versions): New function.
(get_version): New function.

Diff:
---
 gcc/c-family/c-attribs.cc |  4 +++-
 gcc/tree.cc   | 57 +++
 gcc/tree.h| 11 +
 3 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 5a0e3d328ba7..5dff489fccae 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -6132,7 +6132,9 @@ handle_target_clones_attribute (tree *node, tree name, 
tree ARG_UNUSED (args),
}
}
 
-  if (get_target_clone_attr_len (args) == -1)
+  auto_vec versions= get_clone_attr_versions (args, NULL);
+
+  if (versions.length () == 1)
{
  warning (OPT_Wattributes,
   "single % attribute is ignored");
diff --git a/gcc/tree.cc b/gcc/tree.cc
index eccfcc89da40..ddbe98e1a74f 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -15372,6 +15372,63 @@ get_target_clone_attr_len (tree arglist)
   return str_len_sum;
 }
 
+/* Returns an auto_vec of string_slices containing the version strings from
+   ARGLIST.  DEFAULT_COUNT is incremented for each default version found.  */
+
+auto_vec
+get_clone_attr_versions (const tree arglist, int *default_count)
+{
+  gcc_assert (TREE_CODE (arglist) == TREE_LIST);
+  auto_vec versions;
+
+  static const char separator_str[] = {TARGET_CLONES_ATTR_SEPARATOR, 0};
+  string_slice separators = string_slice (separator_str);
+
+  for (tree arg = arglist; arg; arg = TREE_CHAIN (arg))
+{
+  string_slice str = string_slice (TREE_STRING_POINTER (TREE_VALUE (arg)));
+  while (str.is_valid ())
+   {
+ string_slice attr = string_slice::tokenize (&str, separators);
+ attr = attr.strip ();
+
+ if (attr == "default" && default_count)
+   (*default_count)++;
+ versions.safe_push (attr);
+   }
+}
+  return versions;
+}
+
+/* Returns an auto_vec of string_slices containing the version strings from
+   the target_clone attribute from DECL.  DEFAULT_COUNT is incremented for each
+   default version found.  */
+auto_vec
+get_clone_versions (const tree decl, int *default_count)
+{
+  tree attr = lookup_attribute ("target_clones", DECL_ATTRIBUTES (decl));
+  if (!attr)
+return auto_vec ();
+  tree arglist = TREE_VALUE (attr);
+  return get_clone_attr_versions (arglist, default_count);
+}
+
+/* Only works for target_version due to target attributes allowing multiple
+   string arguments to specify one target.  */
+string_slice
+get_target_version (const tree decl)
+{
+  gcc_assert (!TARGET_HAS_FMV_TARGET_ATTRIBUTE);
+
+  tree attr = lookup_attribute ("target_version", DECL_ATTRIBUTES (decl));
+
+  if (!attr)
+return string_slice::invalid ();
+
+  return string_slice (TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr
+  .strip ();
+}
+
 void
 tree_cc_finalize (void)
 {
diff --git a/gcc/tree.h b/gcc/tree.h
index 55f97f9f9994..e34a49a9ed9e 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "tree-core.h"
 #include "options.h"
+#include "vec.h"
 
 /* Convert a target-independent built-in function code to a combined_fn.  */
 
@@ -7041,4 +7042,14 @@ extern tree get_attr_nonstring_decl (tree, tree * = 
NULL);
 
 extern int get_target_clone_attr_len (tree);
 
+/* Returns the version string for a decl with target_version attribute.
+   Returns an invalid string_slice if no attribute is present.  */
+extern string_slice get_target_version (const tree);
+/* Returns a vector of the version strings from a target_clones attribute on
+   a decl.  Can also record the number of default versions found.  */
+extern auto_vec get_clone_versions (const tree, int * = NULL);
+/* Returns a vector of the version strings from a target_clones attribute
+   directly.  */
+extern auto_vec get_clone_attr_versions (const tree, int *);
+
 #endif  /* GCC_TREE_H  */