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.