diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c index 2fa9f325360..362ff3fdac2 100644 --- a/gcc/dwarf2cfi.c +++ b/gcc/dwarf2cfi.c @@ -1695,9 +1695,19 @@ dwarf2out_frame_debug_expr (rtx expr) if (fde && fde->stack_realign && REGNO (src) == STACK_POINTER_REGNUM) - gcc_assert (REGNO (dest) == HARD_FRAME_POINTER_REGNUM - && fde->drap_reg != INVALID_REGNUM - && cur_cfa->reg != dwf_regno (src)); + { + gcc_assert (REGNO (dest) == HARD_FRAME_POINTER_REGNUM + && fde->drap_reg != INVALID_REGNUM + && cur_cfa->reg != dwf_regno (src) + && fde->rule18); + fde->rule18 = 0; + /* The save of hard frame pointer has been deferred + until this point when Rule 18 applied. Emit it now. */ + queue_reg_save (dest, NULL_RTX, 0); + /* And as the instruction modifies the hard frame pointer, + flush the queue as well. */ + dwarf2out_flush_queued_reg_saves (); + } else queue_reg_save (src, dest, 0); } @@ -1907,6 +1917,7 @@ dwarf2out_frame_debug_expr (rtx expr) { gcc_assert (cur_cfa->reg != dw_frame_pointer_regnum); cur_trace->cfa_store.offset = 0; + fde->rule18 = 1; } if (cur_cfa->reg == dw_stack_pointer_regnum) @@ -2041,7 +2052,17 @@ dwarf2out_frame_debug_expr (rtx expr) span = NULL; if (!span) - queue_reg_save (src, NULL_RTX, offset); + { + if (fde->rule18) + /* Just verify the hard frame pointer save when doing dynamic + realignment uses expected offset. The actual queue_reg_save + needs to be deferred until the instruction that sets + hard frame pointer to stack pointer, see PR99334 for + details. */ + gcc_assert (known_eq (offset, 0)); + else + queue_reg_save (src, NULL_RTX, offset); + } else { /* We have a PARALLEL describing where the contents of SRC live. @@ -2732,6 +2753,7 @@ scan_trace (dw_trace_info *trace, bool entry) create_trace_edges (control); } + gcc_assert (!cfun->fde || !cfun->fde->rule18); add_cfi_insn = NULL; cur_row = NULL; cur_trace = NULL; diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h index d659a96e0ab..76a9c0a39a2 100644 --- a/gcc/dwarf2out.h +++ b/gcc/dwarf2out.h @@ -108,6 +108,12 @@ struct GTY(()) dw_fde_node { /* True iff dw_fde_second_begin label is in text_section or cold_text_section. */ unsigned second_in_std_section : 1; + /* True if Rule 18 described in dwarf2cfi.c is in action, i.e. for dynamic + stack realignment in between pushing of hard frame pointer to stack + and setting hard frame pointer to stack pointer. The register save for + hard frame pointer register should be emitted only on the latter + instruction. */ + unsigned rule18 : 1; };