Hi! On PowerPC64 PR50191 testcase when linked together with other code results in linker crash. The problem is that a reference to a constant pool stays in the .debug_loc section. During var-tracking adjust_insn doesn't successfully avoid_constant_pool_reference it because instead of a REG it uses a DEBUG_EXPR (as the register is no longer live at that point), and rs6000_delegitimize_address checks only for REGs in that part of the TOCREL expression. And in dwarf2out.c we were prefering DW_OP_deref* over avoid_constant_pool_reference, performed the latter only if mem_loc_descriptor on the address failed.
The following patch changes it to prefer avoid_constant_pool_reference. I think we can do this in mem_loc_descriptor, because MEMs handled by that routine are otherwise DW_OP_deref*, i.e. DWARF expression rvalues anyway. I'm not changing loc_descriptor, because there we want to prefer getting a REG or MEM which can be changed. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2011-09-05 Jakub Jelinek <ja...@redhat.com> PR debug/50191 * dwarf2out.c (mem_loc_descriptor) <case MEM>: Try avoid_constant_pool_reference first instead of last. --- gcc/dwarf2out.c.jj 2011-07-29 17:07:20.000000000 +0200 +++ gcc/dwarf2out.c 2011-09-05 09:59:41.000000000 +0200 @@ -11695,12 +11695,22 @@ mem_loc_descriptor (rtx rtl, enum machin break; 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); if (mem_loc_result == NULL) mem_loc_result = tls_mem_loc_descriptor (rtl); - if (mem_loc_result != 0) + if (mem_loc_result != NULL) { if (GET_MODE_SIZE (mode) > DWARF2_ADDR_SIZE || GET_MODE_CLASS (mode) != MODE_INT) @@ -11728,12 +11738,6 @@ mem_loc_descriptor (rtx rtl, enum machin new_loc_descr (DW_OP_deref_size, GET_MODE_SIZE (mode), 0)); } - else - { - rtx new_rtl = avoid_constant_pool_reference (rtl); - if (new_rtl != rtl) - return mem_loc_descriptor (new_rtl, mode, mem_mode, initialized); - } break; case LO_SUM: Jakub