Fix target clone indirection elimination
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 (redirect_to_specific_clone): Fix tests to check individual attribute rather than an attribute list. gcc/testsuite * gcc.target/i386/pr95778-1.c: New test. * gcc.target/i386/pr95778-2.c: New test.
This commit is contained in:
parent
67161d24f4
commit
00e90d3d4c
3 changed files with 46 additions and 2 deletions
|
@ -483,7 +483,8 @@ 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 +495,8 @@ 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);
|
||||
|
|
21
gcc/testsuite/gcc.target/i386/pr95778-1.c
Normal file
21
gcc/testsuite/gcc.target/i386/pr95778-1.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* { dg-do compile { target fpic } } */
|
||||
/* { dg-options "-O3 -fPIC -fno-asynchronous-unwind-tables" } */
|
||||
/* { dg-require-ifunc "" } */
|
||||
|
||||
__attribute__((target_clones("default,avx2")))
|
||||
static int
|
||||
f2(int *p)
|
||||
{
|
||||
asm volatile ("" :: "r"(p) : "memory");
|
||||
return *p;
|
||||
}
|
||||
|
||||
__attribute__((target_clones("default,avx2")))
|
||||
int
|
||||
g2(int *p)
|
||||
{
|
||||
return f2(p);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "g2.default.1:\n\tjmp\tf2.default.1\n" } } */
|
||||
/* { dg-final { scan-assembler "g2.avx2.0:\n\tjmp\tf2.avx2.0\n" } } */
|
21
gcc/testsuite/gcc.target/i386/pr95778-2.c
Normal file
21
gcc/testsuite/gcc.target/i386/pr95778-2.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* { dg-do compile { target fpic } } */
|
||||
/* { dg-options "-O3 -fPIC -fno-asynchronous-unwind-tables" } */
|
||||
/* { dg-require-ifunc "" } */
|
||||
|
||||
__attribute__((visibility("internal"),target_clones("default,avx2")))
|
||||
int
|
||||
f2(int *p)
|
||||
{
|
||||
asm volatile ("" :: "r"(p) : "memory");
|
||||
return *p;
|
||||
}
|
||||
|
||||
__attribute__((target_clones("default,avx2")))
|
||||
int
|
||||
g2(int *p)
|
||||
{
|
||||
return f2(p);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "g2.default.1:\n\tjmp\tf2.default.1\n" } } */
|
||||
/* { dg-final { scan-assembler "g2.avx2.0:\n\tjmp\tf2.avx2.0\n" } } */
|
Loading…
Add table
Reference in a new issue