https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122430

--- Comment #12 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
the problem here is that get_availability returns AVAILABLE which makes
get_ipa_modref_summary believe that it can use the summary on g.
This is because of:

  /* If the function can be overwritten, return OVERWRITABLE.  Take
     care at least of two notable extensions - the COMDAT functions
     used to share template instantiations in C++ (this is symmetric
     to code cp_cannot_inline_tree_fn and probably shall be shared and
     the inlinability hooks completely eliminated).  */

  else if (decl_replaceable_p (decl, semantic_interposition)
           && !DECL_EXTERNAL (decl))
    avail = AVAIL_INTERPOSABLE;

now g is DECL_EXTERNAL because of partitioning and that should not overwrite
decl_replaceable_p. That test is somewhat fragile (but is also old). It
basically assumes that DECL_EXTERNAL + knowledge of body implies function keyed
to other unit. cp_cannot_inline_tree_fn does not exists since 2007.  I wonder
if we have more robust way to check for this, but on the other hand it probably
does not make sense for frontend to produce DECL_EXTERNAL function body if it
is completely unuseable.

This patch fixes the miscompilation
diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 508a5559569..13efe89ebba 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -2833,7 +2833,7 @@ cgraph_node::get_availability (symtab_node *ref)
      the inlinability hooks completely eliminated).  */

   else if (decl_replaceable_p (decl, semantic_interposition)
-          && !DECL_EXTERNAL (decl))
+          && (!DECL_EXTERNAL (decl) || in_other_partition))
     avail = AVAIL_INTERPOSABLE;
   else avail = AVAIL_AVAILABLE;

Turning that testcase into testsuite form would be nice.  Will try with
__builtin_constant_p, but the DSE change is happening late.

Reply via email to