]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rs6000: Don't use HARD_FRAME_POINTER_REGNUM if it's not live in pro_and_epilogue...
authorXionghu Luo <luoxhu@linux.ibm.com>
Mon, 11 May 2020 01:27:38 +0000 (20:27 -0500)
committerXionghu Luo <luoxhu@linux.ibm.com>
Mon, 11 May 2020 01:30:56 +0000 (20:30 -0500)
Backport from master.

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 when generating pro_and_epilogue
instructions.

gcc/ChangeLog

2020-05-11  Xiong Hu Luo  <luoxhu@linux.ibm.com>

Backport from master.
2020-04-27  Xiong Hu Luo  <luoxhu@linux.ibm.com>

PR target/91518
* config/rs6000/rs6000.c (frame_pointer_needed_indeed):
New variable.
(rs6000_emit_prologue_components):
Check with frame_pointer_needed_indeed.
(rs6000_emit_epilogue_components): Likewise.
(rs6000_emit_prologue): Likewise.
(rs6000_emit_epilogue): Set frame_pointer_needed_indeed.

gcc/ChangeLog
gcc/config/rs6000/rs6000.c

index 3fad79c3706b80cf8338855949b07dd4ee8502ee..fc71ca1384f9a173390ab6f371febfaa08571f84 100644 (file)
@@ -1,4 +1,18 @@
-2020-05-07  Uroš Bizjak  <ubizjak@gmail.com>
+2020-05-11  Xiong Hu Luo  <luoxhu@linux.ibm.com>
+
+       Backport from master.
+       2020-04-27  Xiong Hu Luo  <luoxhu@linux.ibm.com>
+
+       PR target/91518
+       * config/rs6000/rs6000.c (frame_pointer_needed_indeed):
+       New variable.
+       (rs6000_emit_prologue_components):
+       Check with frame_pointer_needed_indeed.
+       (rs6000_emit_epilogue_components): Likewise.
+       (rs6000_emit_prologue): Likewise.
+       (rs6000_emit_epilogue): Set frame_pointer_needed_indeed.
+
+2020-05-07 Uroš Bizjak  <ubizjak@gmail.com>
 
        * config/alpha/alpha.c (alpha_atomic_assign_expand_fenv): Use
        TARGET_EXPR instead of MODIFY_EXPR for the first assignments to
index 8043cbc875273d129ef3e57a0f8db7a02ffa950c..ce76f039aeda10ad2b5480e730bcb1a3f60b534f 100644 (file)
@@ -20908,6 +20908,9 @@ rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
 \f
 static rs6000_stack_t stack_info;
 
+/* Set if HARD_FRAM_POINTER_REGNUM is really needed.  */
+static bool frame_pointer_needed_indeed = false;
+
 /* Function to init struct machine_function.
    This will be called, via a pointer variable,
    from push_function_context.  */
@@ -26842,9 +26845,9 @@ static 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
+                                     ? HARD_FRAME_POINTER_REGNUM
+                                     : STACK_POINTER_REGNUM);
 
   machine_mode reg_mode = Pmode;
   int reg_size = TARGET_32BIT ? 4 : 8;
@@ -26922,9 +26925,9 @@ static 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
+                                     ? HARD_FRAME_POINTER_REGNUM
+                                     : STACK_POINTER_REGNUM);
 
   machine_mode reg_mode = Pmode;
   int reg_size = TARGET_32BIT ? 4 : 8;
@@ -27102,7 +27105,10 @@ rs6000_emit_prologue (void)
                            && (lookup_attribute ("no_split_stack",
                                                  DECL_ATTRIBUTES (cfun->decl))
                                == NULL));
+
+  frame_pointer_needed_indeed
+    = frame_pointer_needed && df_regs_ever_live_p (HARD_FRAME_POINTER_REGNUM);
+
   /* Offset to top of frame for frame_reg and sp respectively.  */
   HOST_WIDE_INT frame_off = 0;
   HOST_WIDE_INT sp_off = 0;
@@ -27764,7 +27770,7 @@ rs6000_emit_prologue (void)
     }
 
   /* Set frame pointer, if needed.  */
-  if (frame_pointer_needed)
+  if (frame_pointer_needed_indeed)
     {
       insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
                             sp_reg_rtx);
@@ -28608,7 +28614,7 @@ rs6000_emit_epilogue (int sibcall)
     }
   /* 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)
     {
       frame_reg_rtx = sp_reg_rtx;
       if (DEFAULT_ABI == ABI_V4)