https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128270
--- Comment #2 from Uroš Bizjak <ubizjak at gmail dot com> --- The missing .cfi_restore 6 is caused by the red-zone early return in ix86_add_cfa_restore_note, not by dwarf2cfi or ix86_emit_leave. With DRAP, the prologue saves the caller’s %rbp with a DW_CFA_expression rule (breg6 (rbp) + 0, the .cfi_escape 0x10,0x6,0x2,0x76,0), so the rule is evaluated through %rbp itself. After leave (or popq %rbp), %rbp holds the caller’s value, and the stale rule then reads from the wrong address. gdb shows a truncated backtrace if you stop right after leave. ix86_add_cfa_restore_note skips the note when cfa_offset <= red_zone_offset, on the assumption that “unwinders can find the same value in the register and on the stack”. That holds for a DW_CFA_offset rule but not for the DRAP expression rule. Evidence: * At -DALIGN=32, insn 28 in .pro_and_epilogue is a plain insn with (nil) notes. At -DALIGN=128 it is insn/f with REG_CFA_RESTORE (reg/f:DI 6 bp). The save slot is outside the red zone in the larger frame, which is why larger alignments appeared to fix it. * -mno-red-zone at -DALIGN=32 emits .cfi_restore 6 after leave. * -mtune-ctrl=^use_leave at -DALIGN=32 emits popq %rbp with no restore. The same helper is used by ix86_emit_restore_reg_using_pop.
