Hi, This is regarding PR122274 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122274). In brief, the issue (which is explained in greater detail in the PR) is as follows:
The following RTL is the input to cprop_hardreg pass: BB2: insn 38: set r5, lr ... BB3: ... ... BB4: insn/f 44: set r0, lr insn/f 45: set [stack_mem], r0 insn 46: call <foo> ... Instructions 44 & 45 belong to the prolog and have been placed in BB4 by shrink wrap pass. ‘lr’ is the link register. After cprop_hardreg, BB4 is as follows: BB4: insn/f 44: set r0, lr insn/f 45: set [stack_mem], r5 insn 46: call <foo> There are no other uses of r0, and so in the DCE pass, insn 44 is deleted. This results in the following Call Frame Instructions being generated: DW_CFA_advance_loc: 60 to 000000000001a7dc DW_CFA_def_cfa_offset: 32 DW_CFA_offset_extended_sf: r5 at cfa+16 DW_CFA_advance_loc: 16 to 000000000001a7ec DW_CFA_def_cfa_offset: 0 DW_CFA_advance_loc: 8 to 000000000001a7f4 DW_CFA_restore_extended: r65 DW_CFA_nop DW_CFA_nop DW_CFA_nop This doesn’t tell us that the ‘lr’ register is at cfa+16. Due to this, we are facing issues during stack unwinding. What cprop_hardreg didn't take into account was that the setup of r5 (insn 38) was not frame related but the setup of r0 was, and it's now substituting something _into_ a frame-related insn. So the connection between insn 44 and 45 (via the frame-relatedness) that dwarf2out needs to figure out unwind info is lost. Insn 44 is then also deleted, but that itself isn't the problem, it's the loss of connection between insn 38 (ex-44) and insn 45 that is. To address the issue, cprop_hardreg should not deem a non-frame-related insn equivalent to a frame-related one, at least not when the target of propagation is a use in a frame-related insn itself. cprop_hardreg uses ‘struct value_data’ to hold lists of registers that contain the same value. However, the value data does not have any information about the instruction that sets the values in the register. We can extend this data structure such that we add a new field to ’struct value_data_entry’ which indicates if the instruction that created this value is frame related or not. Then during copy propagation, we do not replace registers if the copy is happening from a non-frame related insn to a frame related insn. Before moving forward, I’d appreciate feedback from the community on whether this approach is fine. Regards, Surya
