Hi, In the attached testcase, IPA-SRA thinks that an ifunc resolver (meanwhile IPA-split into two functions) function can be changed and so goes ahead. The cgraph machinery then however throws away the new clone of the caller instead of the "old" caller and inliner inlines the clone of the ".part" function into the original resolver, which results into an interesting miscompilation because IPA-SRA counted on that both the caller and the callee are modified.
Fixed by making cgraph_node::can_be_local_p return false for ifunc resolvers, as it should. The patch also adds dumping of the symtab_node flag. Bootstrapped and tested on x86_64-linux, OK for trunk? Thanks, Martin 2019-11-27 Martin Jambor <mjam...@suse.cz> PR ipa/92697 * cgraph.c (cgraph_node_cannot_be_local_p_1): Return true for ifunc_resolvers. * symtab.c (symtab_node::dump_base): Dump ifunc_resolver flag. Removed trailig whitespace. testsuite/ * g++.dg/ipa/pr92697.C: New. --- gcc/cgraph.c | 1 + gcc/symtab.c | 4 ++- gcc/testsuite/g++.dg/ipa/pr92697.C | 51 ++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/ipa/pr92697.C diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 1f7a5c58d98..dd07516b83e 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -2227,6 +2227,7 @@ static bool cgraph_node_cannot_be_local_p_1 (cgraph_node *node, void *) { return !(!node->force_output + && !node->ifunc_resolver && ((DECL_COMDAT (node->decl) && !node->forced_by_abi && !node->used_from_object_file_p () diff --git a/gcc/symtab.c b/gcc/symtab.c index 3e634e22c86..5a3122fc8bb 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -914,8 +914,10 @@ symtab_node::dump_base (FILE *f) if (DECL_STATIC_DESTRUCTOR (decl)) fprintf (f, " destructor"); } + if (ifunc_resolver) + fprintf (f, " ifunc_resolver"); fprintf (f, "\n"); - + if (same_comdat_group) fprintf (f, " Same comdat group as: %s\n", same_comdat_group->dump_asm_name ()); diff --git a/gcc/testsuite/g++.dg/ipa/pr92697.C b/gcc/testsuite/g++.dg/ipa/pr92697.C new file mode 100644 index 00000000000..8958bd0dcf2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr92697.C @@ -0,0 +1,51 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O2 -fdump-ipa-sra" } */ + +extern int have_avx2; +extern int have_ssse3; + +namespace NTL +{ + + static void randomstream_impl_init_base () + { + __builtin_printf ("Frob1\n"); + } + + static void // __attribute__ ((target ("ssse3"))) + randomstream_impl_init_ssse3 () + { + __builtin_printf ("Frob2\n"); + } + + static void + //__attribute__ ((target ("avx2,fma,avx,pclmul,ssse3"))) + randomstream_impl_init_avx2 () + { + __builtin_printf ("Frob3\n"); + } + + extern "C" + { + static void (*resolve_randomstream_impl_init (void)) () + { + if (have_avx2) + return &randomstream_impl_init_avx2; + if (have_ssse3) + return &randomstream_impl_init_ssse3; + return &randomstream_impl_init_base; + } + } + static void + __attribute__ ((ifunc ("resolve_" "randomstream_impl_init"))) + randomstream_impl_init (); + void foo () + { + randomstream_impl_init (); + } + +} + + +/* { dg-final { scan-ipa-dump-not "Created new node" "sra" } } */ -- 2.24.0