Fix can_be_discarded_p wrt partitioned functions

Jan Hubicka hubicka@kam.mff.cuni.cz
Sat Nov 6 22:40:43 GMT 2021


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)


More information about the Gcc-patches mailing list