Hi, this patch fixes gcc.dg/lto/pr56297 failure. Here we have two modules defining global variable assigned to hard registers. Those variables do not go into assembler name hash because they have no real assembler name and consequentely they are not merged. We however may end up with two declarations being merged by tree merging and then symtab needs to compensate. We solve precisely same problem for builtins and abstract functions already. This patch thus makes us to do the right thing for variables, too.
I also added comment since the code is bit weird. Bootstrapped/regtested x86_64-linux, will commit it shortly. Honza * lto-symtab.c (lto_symtab_merge_symbols): Add comments; merge duplicated nodes for assembler names. * symtab.c (symtab_unregister_node): Do not attempt to unlink hard registers from assembler name hash. Index: lto-symtab.c =================================================================== --- lto-symtab.c (revision 202182) +++ lto-symtab.c (working copy) @@ -586,6 +586,9 @@ lto_symtab_merge_symbols (void) FOR_EACH_SYMBOL (node) { cgraph_node *cnode, *cnode2; + varpool_node *vnode; + symtab_node node2; + if (!node->symbol.analyzed && node->symbol.alias_target) { symtab_node tgt = symtab_node_for_asm (node->symbol.alias_target); @@ -594,22 +597,37 @@ lto_symtab_merge_symbols (void) symtab_resolve_alias (node, tgt); } node->symbol.aux = NULL; - + if (!(cnode = dyn_cast <cgraph_node> (node)) || !cnode->clone_of || cnode->clone_of->symbol.decl != cnode->symbol.decl) { + /* Builtins are not merged via decl merging. It is however + possible that tree merging unified the declaration. We + do not want duplicate entries in symbol table. */ if (cnode && DECL_BUILT_IN (node->symbol.decl) && (cnode2 = cgraph_get_node (node->symbol.decl)) && cnode2 != cnode) lto_cgraph_replace_node (cnode2, cnode); + /* The user defined assembler variables are also not unified by their + symbol name (since it is irrelevant), but we need to unify symbol + nodes if tree merging occured. */ + if ((vnode = dyn_cast <varpool_node> (node)) + && DECL_HARD_REGISTER (vnode->symbol.decl) + && (node2 = symtab_get_node (vnode->symbol.decl)) + && node2 != node) + lto_varpool_replace_node (dyn_cast <varpool_node> (node2), + vnode); + + /* Abstract functions may have duplicated cgraph nodes attached; remove them. */ else if (cnode && DECL_ABSTRACT (cnode->symbol.decl) && (cnode2 = cgraph_get_node (node->symbol.decl)) && cnode2 != cnode) cgraph_remove_node (cnode2); + symtab_insert_node_to_hashtable ((symtab_node)node); } } Index: symtab.c =================================================================== --- symtab.c (revision 202182) +++ symtab.c (working copy) @@ -283,7 +283,8 @@ symtab_unregister_node (symtab_node node else *slot = replacement_node; } - unlink_from_assembler_name_hash (node, false); + if (!is_a <varpool_node> (node) || !DECL_HARD_REGISTER (node->symbol.decl)) + unlink_from_assembler_name_hash (node, false); } /* Return symbol table node associated with DECL, if any,