Hi, can_be_discarded_p is testing DECL_EXTERNAL flag to see if the symbol can be discarded by linker if unreachable. This is meant to catch extern inline functions (which is bit side case and it is intded to avoid gcc from producing new references to them if there were no refernces before) but it mistakely also matches partitioned functions during LTO. This led to the ICE with sanity check I added to gimple_call_static_chain_flags since we suddenly got interposable nested functions.
This is fixed by the patch and I checked I can build the failing testcases with the sanity check re-instatiated which I plan to do after some more testing. ltobootstrapped/regtested x86_64. Comitte. Honza gcc/ChangeLog: * cgraph.h (cgraph_node::can_be_discarded_p): Do not return true on functions from other partition. gcc/lto/ChangeLog: PR ipa/103070 PR ipa/103058 * lto-partition.c (must_not_rename): Update comment. (promote_symbol): Set resolution to LDPR_PREVAILING_DEF_IRONLY. diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 4cdb3738b4d..0a1f7c8960e 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -404,7 +404,8 @@ public: inline bool can_be_discarded_p (void) { - return (DECL_EXTERNAL (decl) + return ((DECL_EXTERNAL (decl) + && !in_other_partition) || ((get_comdat_group () || DECL_COMMON (decl) || (DECL_SECTION_NAME (decl) && DECL_WEAK (decl))) diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c index 15761ac9eb5..bee40218159 100644 --- a/gcc/lto/lto-partition.c +++ b/gcc/lto/lto-partition.c @@ -852,7 +852,9 @@ must_not_rename (symtab_node *node, const char *name) /* Avoid mangling of already mangled clones. ??? should have a flag whether a symbol has a 'private' name already, since we produce some symbols like that i.e. for global constructors - that are not really clones. */ + that are not really clones. + ??? it is what unique_name means. We only need to set it when doing + private symbols. */ if (node->unique_name) { if (dump_file) @@ -995,6 +997,10 @@ promote_symbol (symtab_node *node) defined by the non-LTO part. */ privatize_symbol_name (node); TREE_PUBLIC (node->decl) = 1; + /* After privatization the node should not conflict with any other symbol, + so it is prevailing. This is important to keep binds_to_current_def_p + to work across partitions. */ + node->resolution = LDPR_PREVAILING_DEF_IRONLY; DECL_VISIBILITY (node->decl) = VISIBILITY_HIDDEN; DECL_VISIBILITY_SPECIFIED (node->decl) = true; if (dump_file)