http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50191

--- Comment #12 from Jakub Jelinek <jakub at gcc dot gnu.org> 2011-09-05 
08:23:56 UTC ---
The problem is that at var-tracking time the expression contains another
debug_expr (as at that point the register 12 which held the toc address is no
longer live):
(debug_insn 9141 9142 8803 4 (var_location:DI D#142 (mem/u/c:DI (lo_sum:DI
(debug_expr:DI D#146)
            (const:DI (unspec:DI [
                        (symbol_ref/u:DI ("*.LC8") [flags 0x2])
                    ] UNSPEC_TOCREL))) [23 S8 A8])) -1
     (nil))
and rs6000_delegitimize_address only delegitimizes if it is a register:
          && ((GET_CODE (XEXP (x, 0)) == REG
               && (REGNO (XEXP (x, 0)) == TOC_REGISTER
                   || TARGET_MINIMAL_TOC
                   || TARGET_CMODEL != CMODEL_SMALL))
So this isn't delegitmized nor avoid_constant_pool_reference transformed at
var-tracking time.  At dwarf2out.c, it is delegitimized, but mem_loc_descriptor
attempts to avoid_constant_pool_reference only if emitting a DW_OP_deref*
failed.  I'll attach a patch which attempts avoid_constant_pool_reference there
first, which is one way of fixing this.  Another would be to handle DEBUG_EXPR
the same as REG, i.e. add || (GET_CODE (XEXP (x, 0)) == DEBUG_EXPR &&
(TARGET_MINIMAL_TOC || TARGET_CMODEL != CMODEL_SMALL)) to the condition (and,
btw, the GET_CODE ... == REG should be replaced with REG_P (...)).
I'd say we want both, as while I can do this change in mem_loc_descriptor, I
can't do it in loc_descriptor where we strongly want to prefer a MEM over
avoid_constant_pool_reference.
That said, I doubt we can guarantee that gcc will never emit something like
that, even with both of the patches.  So IMHO the linker needs to be fixed
nevertheless.

Reply via email to