The current logic seems to be comparing the whole attribute tree between the callee and caller (or at least the tree starting from the target attribute). This is unnecessary and causes strange dependency of the indirection elimination on unrelated properties like `noinline`(PR95780) and `visibility`(PR95778).
This changes the comparison to be only on the `target` attribute which should be the intent of the code. --- gcc/multiple_target.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/multiple_target.c b/gcc/multiple_target.c index c1cfe8ff978..9eb0afd58cc 100644 --- a/gcc/multiple_target.c +++ b/gcc/multiple_target.c @@ -483,7 +483,7 @@ redirect_to_specific_clone (cgraph_node *node) DECL_ATTRIBUTES (e->callee->decl)); /* Function is not calling proper target clone. */ - if (!attribute_list_equal (attr_target, attr_target2)) + if (attr_target2 == NULL_TREE || !attribute_value_equal (attr_target, attr_target2)) { while (fv2->prev != NULL) fv2 = fv2->prev; @@ -494,7 +494,7 @@ redirect_to_specific_clone (cgraph_node *node) cgraph_node *callee = fv2->this_node; attr_target2 = lookup_attribute ("target", DECL_ATTRIBUTES (callee->decl)); - if (attribute_list_equal (attr_target, attr_target2)) + if (attr_target2 != NULL_TREE && attribute_value_equal (attr_target, attr_target2)) { e->redirect_callee (callee); cgraph_edge::redirect_call_stmt_to_callee (e); -- 2.27.0