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

Reply via email to