http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51957
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-01-23 10:48:05 UTC --- The problem is that during var-tracking adjust_insn doesn't avoid_constant_pool_reference because we have: (debug_insn 116 33 34 5 (var_location:DI D#3 (reg:DI 2 2)) -1 (nil)) ... (debug_insn 114 37 113 5 (var_location:DI D#2 (mem/u/c:DI (plus:DI (debug_expr:DI D#3) (const:DI (unspec:DI [ (symbol_ref/u:DI ("*.LC0") [flags 0x2]) ] UNSPEC_TOCREL))) [8 S8 A8])) -1 (nil)) and thus rs6000_delegitimize_address doesn't do anything (as there is DEBUG_EXPR not REG 2 directly). This means the UNSPEC_TOCREL stuff gets down into mem_loc_descriptor (with (reg:DI 2) in it). There it is successfully delegitimized and we do: case MEM: { rtx new_rtl = avoid_constant_pool_reference (rtl); if (new_rtl != rtl) { mem_loc_result = mem_loc_descriptor (new_rtl, mode, mem_mode, initialized); if (mem_loc_result != NULL) return mem_loc_result; } } mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), get_address_mode (rtl), mode, VAR_INIT_STATUS_INITIALIZED); While mem_loc_descriptor here (unlike loc_descriptor or some other places) tries avoid_constant_pool_reference first, mem_loc_descriptor for that fails (because (symbol_ref "w") is external and so it falls back to DW_OP_deref on the .LC0 symbol (but that is apparently what ppc64 ld doesn't like). On other targets, trying to fallback to the original mem can be a win, if say we end up dereferencing some word in .got and the linker is fine with it, we can provide the value to the debugger. So I'd say that ppc64 should have some target hook that would say that (at least certain kind of) mem/u/c (on ppc64 if we can limit them to .toc section references if possible) should never be referenced in the .debug_info/.debug_loc (or could it be on the symbol_ref's only, can we from the symbol_ref find out that it is a symbol from .toc section?). Alan, what do you think about this?