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

            Bug ID: 101454
           Summary: debug info for unreachable var forces another var to
                    be output
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: debug
          Assignee: unassigned at gcc dot gnu.org
          Reporter: aoliva at gcc dot gnu.org
  Target Milestone: ---

If some IPA pass replaces the only reference to a constant non-public
non-automatic variable with its initializer, namely the address of another such
variable, the former becomes unreferenced and it's discarded by
symbol_table::remove_unreachable_nodes.  It calls debug_hooks->late_global_decl
while at that, and this expands the initializer, which assigs RTL to the latter
variable and forces it to be retained by remove_unreferenced_decls, and
eventually be output despite not being referenced.  Without debug information,
it's not output.

This has caused a bootstrap-debug compare failure in libdecnumber/decContext.o,
while developing a transformation that ends up enabling the above substitution
in constprop.

I've proposed a patch that makes reference_to_unused slightly more conservative
about such variables at the end of IPA passes, falling back onto
expand_debug_expr for expressions referencing symbols that might or might not
be output, avoiding the loss of debug information when the symbol is output,
while avoiding a symbol output only because of debug info.
https://gcc.gnu.org/pipermail/gcc-patches/2021-July/575043.html

richi suggested using symbolic DIE references, later resolved by
note_variable_values.  Maybe we do this unconditionally for the initializers of
removed decls.  That seems doable and desirable.  decContext.c doesn't generate
location or const_value for neither mfctop nor mfcone, even after removing
rtl_for_decl_location from add_location_or_const_value_attribute, despite
lookup_decl_loc's finding a location expression.

Alas, I haven't managed to come up with a testcase to trigger the problem
without the patchset that I'm not yet ready to contribute.
https://gcc.gnu.org/pipermail/gcc/2021-July/236780.html

The kicker, in case someone wants to force it, is that at
materialize_all_clones, the reference to mfctop in a constprop-ed
decContextTestEndian gets substituted by its constant initializer, &mfcone, so
mfctop becomes unreachable and goes through late_global_decl in
remove_unreachable_nodes.  Eventually, ccp2 resolves the mfcone dereference to
a constant, and no reason remains for mfcone to be output.  However, when
outputting debug info, the expand_expr of mfctop's initializer will have
already generated RTL for mfcone, committing it to be output, wehreas without
debug info, mfcone is not output at all.

What enables these transformations during IPA is the introduction of a wrapper
for decContextTestEndian, moving its body to a clone that is materialized
early, at the end of all_small_ipa_passes.  This clone, being a local function,
seems to be what enables the substitution of the mfctop constant initializer. 
I haven't found a way to cause such a difference without my pass, even getting
a constprop (local) clone for the function, and preventing its inlining into an
exported function.

Hopefully this is enough information to enable the issue to be investigated.

Reply via email to