https://gcc.gnu.org/g:9c197fe3c2112dab7a520a9cd04e4a0dc5f7f223
commit r16-5157-g9c197fe3c2112dab7a520a9cd04e4a0dc5f7f223 Author: Lulu Cheng <[email protected]> Date: Wed Oct 15 16:55:25 2025 +0800 LoongArch: Implement TARGET_OPTION_SAME_FUNCTION_VERSIONS. gcc/ChangeLog: * config/loongarch/loongarch.cc (loongarch_option_same_function_versions): Compare the target attributes in two functions to determine which function’s features get higher priority. (TARGET_OPTION_SAME_FUNCTION_VERSIONS): Define. Diff: --- gcc/config/loongarch/loongarch.cc | 41 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 57767f6e2863..6d587049102b 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -11671,15 +11671,29 @@ get_feature_mask_for_version (tree decl, { tree version_attr = lookup_attribute ("target_version", DECL_ATTRIBUTES (decl)); + + /* When a function is added with "__attribute__((target_version(**)))" to + define multiple versions, it is allowed to define this function without + adding the "__attribute__((target_version("default")))" attribute. + In this case, the function without the attribute will be compiled as the + default version. + If version_attr is empty, it is the default version of the function. + Set the feature_mask of this function to 0 and the priority to + LA_PRIO_NONE. */ if (version_attr == NULL) - return; + { + if (feature_mask) + feature_mask = 0ULL; + + if (feature_priority) + feature_priority->safe_push (0); + return; + } string_slice version_string = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (version_attr))); loongarch_parse_fmv_features (decl, version_string, feature_mask, feature_priority); - - return; } /* This adds a condition to the basic_block NEW_BB in function FUNCTION_DECL @@ -12027,6 +12041,23 @@ loongarch_generate_version_dispatcher_body (void *node_p) return resolver_decl; } +/* This function returns true if FN1 and FN2 are versions of the same function, + that is, the target_version attributes of the function decls are different. + This assumes that FN1 and FN2 have the same signature. */ + +bool +loongarch_option_same_function_versions (string_slice str1, string_slice str2) +{ + loongarch_fmv_feature_mask feature_mask1; + loongarch_fmv_feature_mask feature_mask2; + loongarch_parse_fmv_features (NULL, str1, + &feature_mask1, NULL); + loongarch_parse_fmv_features (NULL, str2, + &feature_mask2, NULL); + + return feature_mask1 == feature_mask2; +} + /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" @@ -12334,6 +12365,10 @@ loongarch_generate_version_dispatcher_body (void *node_p) #define TARGET_COMPARE_VERSION_PRIORITY \ loongarch_compare_version_priority +#undef TARGET_OPTION_SAME_FUNCTION_VERSIONS +#define TARGET_OPTION_SAME_FUNCTION_VERSIONS \ + loongarch_option_same_function_versions + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-loongarch.h"
