This bug is exposed by FRE refactor of r263875. Comparing the fre dump file shows no obvious change of the segment fault function proves it to be a target issue. frame_pointer_needed is set to true in reload pass setup_can_eliminate, but regs_ever_live[31] is false, pro_and_epilogue uses it without live check causing CPU2006 465.tonto segment fault of loading from invalid addresses due to r31 not saved/restored. Thus, add HARD_FRAME_POINTER_REGNUM live check with frame_pointer_needed_indeed_p when generating pro_and_epilogue instructions.
Bootstrap and regression tested pass on Power8-LE. Backport to gcc-9 required once approved. gcc/ChangeLog 2020-04-13 Xiong Hu Luo <luo...@linux.ibm.com> PR target/91518 * config/rs6000/rs6000-logue.c (frame_pointer_needed_indeed_p): New function. (rs6000_emit_prologue_components): Check with frame_pointer_needed_indeed_p. (rs6000_emit_epilogue_components): Likewise. (rs6000_emit_prologue): Likewise. (rs6000_emit_epilogue): Likewise. --- gcc/config/rs6000/rs6000-logue.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/gcc/config/rs6000/rs6000-logue.c b/gcc/config/rs6000/rs6000-logue.c index 4cbf228eb79..d17876ac0fb 100644 --- a/gcc/config/rs6000/rs6000-logue.c +++ b/gcc/config/rs6000/rs6000-logue.c @@ -2730,14 +2730,22 @@ rs6000_disqualify_components (sbitmap components, edge e, } } +/* Determine whether HARD_FRAM_POINTER_REGNUM is really needed. */ +static bool +frame_pointer_needed_indeed_p (void) +{ + return frame_pointer_needed + && df_regs_ever_live_p (HARD_FRAME_POINTER_REGNUM); +} + /* Implement TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS. */ void rs6000_emit_prologue_components (sbitmap components) { rs6000_stack_t *info = rs6000_stack_info (); - rtx ptr_reg = gen_rtx_REG (Pmode, frame_pointer_needed - ? HARD_FRAME_POINTER_REGNUM - : STACK_POINTER_REGNUM); + rtx ptr_reg = gen_rtx_REG (Pmode, frame_pointer_needed_indeed_p () + ? HARD_FRAME_POINTER_REGNUM + : STACK_POINTER_REGNUM); machine_mode reg_mode = Pmode; int reg_size = TARGET_32BIT ? 4 : 8; @@ -2815,9 +2823,9 @@ void rs6000_emit_epilogue_components (sbitmap components) { rs6000_stack_t *info = rs6000_stack_info (); - rtx ptr_reg = gen_rtx_REG (Pmode, frame_pointer_needed - ? HARD_FRAME_POINTER_REGNUM - : STACK_POINTER_REGNUM); + rtx ptr_reg = gen_rtx_REG (Pmode, frame_pointer_needed_indeed_p () + ? HARD_FRAME_POINTER_REGNUM + : STACK_POINTER_REGNUM); machine_mode reg_mode = Pmode; int reg_size = TARGET_32BIT ? 4 : 8; @@ -3658,7 +3666,7 @@ rs6000_emit_prologue (void) } /* Set frame pointer, if needed. */ - if (frame_pointer_needed) + if (frame_pointer_needed_indeed_p ()) { insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM), sp_reg_rtx); @@ -4534,7 +4542,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) } /* If we have a frame pointer, we can restore the old stack pointer from it. */ - else if (frame_pointer_needed) + else if (frame_pointer_needed_indeed_p ()) { frame_reg_rtx = sp_reg_rtx; if (DEFAULT_ABI == ABI_V4) -- 2.21.0.777.g83232e3864