http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51271
--- Comment #15 from vries at gcc dot gnu.org 2011-12-19 13:17:23 UTC --- > given this definition, maybe insn 141 should be marked as frame-related, since > it restores a reg in the epilogue. It seems to be the other way round: insn 141 is ignored by scan_insn_after, because: - it is not frame-related, and - doesn't contain a REG_ARGS_SIZE note. The problematic insn is insn 143. That one has the REG_CFA notes attached, and is causes changes in cfi state. In scan_trace, we're handling insn 143 as element in the delay slot of an annulling branch, executed only on taken branch: ... (gdb) call debug_rtx (elt) (insn/s/f 143 79 162 (set (reg/f:SI 29 $sp) (plus:SI (reg/f:SI 29 $sp) (const_int 16 [0x10]))) 10 {*addsi3} (expr_list:REG_CFA_DEF_CFA (reg/f:SI 29 $sp) (expr_list:REG_CFA_RESTORE (reg:DI 28 $28) (nil)))) ... The row state at that point is: ... (gdb) call debug_cfi_row (cur_row) .cfi_def_cfa 29, 16 .cfi_offset 28, -8 ... we then execute scan_insn_after to setup the trace at the target of the jump: ... (gdb) 2460 scan_insn_after (elt); .... at which point the REG_CFAs have been taken into account: ... (gdb) call debug_cfi_row (cur_row) .cfi_def_cfa 29, 0 ... we then try to restore for the fallthru path: ... 2467 cur_trace->end_true_args_size = restore_args_size; (gdb) n 2468 cur_row->cfa = this_cfa; (gdb) ... but the state is not sufficiently restored: ... (gdb) call debug_cfi_row (cur_row) .cfi_def_cfa 29, 16 ... The '.cfi_offset 28, -8' is missing. This tentative patch fixes the problem for the testcase: ... Index: src/gcc-mainline/gcc/dwarf2cfi.c =================================================================== --- src/gcc-mainline/gcc/dwarf2cfi.c (revision 182341) +++ src/gcc-mainline/gcc/dwarf2cfi.c (working copy) @@ -2452,10 +2452,12 @@ scan_trace (dw_trace_info *trace) if (INSN_FROM_TARGET_P (elt)) { HOST_WIDE_INT restore_args_size; + cfi_vec save_row_reg_save; add_cfi_insn = NULL; restore_args_size = cur_trace->end_true_args_size; cur_cfa = &cur_row->cfa; + save_row_reg_save = VEC_copy (dw_cfi_ref, gc, cur_row->reg_save); scan_insn_after (elt); @@ -2466,6 +2468,7 @@ scan_trace (dw_trace_info *trace) cur_trace->end_true_args_size = restore_args_size; cur_row->cfa = this_cfa; + cur_row->reg_save = save_row_reg_save; cur_cfa = &this_cfa; continue; } ...