[gcc r15-7090] Add warning for non-spec compliant FMV in Aarch64
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
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
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
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.
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.
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.
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.
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.
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.
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
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'
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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
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.
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 */