aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorYichao Yu <yyc1992@gmail.com>2020-06-26 15:46:15 -0600
committerJeff Law <law@redhat.com>2020-06-26 15:49:52 -0600
commit00e90d3d4cb51fd0fae7b2dbd4bab1db26d6676e (patch)
treeb4822e4fbc21194590e4ecb26d9f5c0b31c6d29d /gcc
parent67161d24f45601e43abea98f2c3d7d7a462b6eab (diff)
downloadgcc-00e90d3d4cb51fd0fae7b2dbd4bab1db26d6676e.zip
gcc-00e90d3d4cb51fd0fae7b2dbd4bab1db26d6676e.tar.gz
gcc-00e90d3d4cb51fd0fae7b2dbd4bab1db26d6676e.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/multiple_target.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/pr95778-1.c21
-rw-r--r--gcc/testsuite/gcc.target/i386/pr95778-2.c21
3 files changed, 46 insertions, 2 deletions
diff --git a/gcc/multiple_target.c b/gcc/multiple_target.c
index c1cfe8f..b15d004 100644
--- a/gcc/multiple_target.c
+++ b/gcc/multiple_target.c
@@ -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);
diff --git a/gcc/testsuite/gcc.target/i386/pr95778-1.c b/gcc/testsuite/gcc.target/i386/pr95778-1.c
new file mode 100644
index 0000000..3238303
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr95778-1.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr95778-2.c b/gcc/testsuite/gcc.target/i386/pr95778-2.c
new file mode 100644
index 0000000..e88702d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr95778-2.c
@@ -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" } } */