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.