diff mbox series

[pushed] LRA: Update insn sp offset if its input reload changes SP

Message ID e7d0b992-d76a-bb47-d2b0-39329e8020cc@redhat.com
State New
Headers show
Series [pushed] LRA: Update insn sp offset if its input reload changes SP | expand

Commit Message

Vladimir Makarov May 30, 2023, 8:05 p.m. UTC
The following patch fixes an LRA bug triggered by switching H8300 target 
from reload to LRA.  The description of the problem is in the commit 
message.

The patch was successfully bootstrapped and tested on x86-64, aarch64, 
and ppc64le.
commit 30038a207c10a2783fa2695b62c7c8458ef05e73
Author: Vladimir N. Makarov <vmakarov@redhat.com>
Date:   Tue May 30 15:54:28 2023 -0400

    LRA: Update insn sp offset if its input reload changes SP
    
    The patch fixes a bug when there is input reload changing SP.  The bug was
    triggered by switching H8300 target to LRA.  The insn in question is
    
    (insn 21 20 22 2 (set (mem/f:SI (pre_dec:SI (reg/f:SI 7 sp)) [3  S4 A32])
            (reg/f:SI 31)) "j.c":10:3 19 {*movsi}
         (expr_list:REG_DEAD (reg/f:SI 31)
            (expr_list:REG_ARGS_SIZE (const_int 4 [0x4])
                (nil))))
    
    The memory address is reloaded but the SP offset for the original insn was not updated.
    
    gcc/ChangeLog:
    
            * lra-int.h (lra_update_sp_offset): Add the prototype.
            * lra.cc (setup_sp_offset): Change the return type.  Use
            lra_update_sp_offset.
            * lra-eliminations.cc (lra_update_sp_offset): New function.
            (lra_process_new_insns): Push the current insn to reprocess if the
            input reload changes sp offset.

Comments

Jeff Law May 30, 2023, 8:28 p.m. UTC | #1
On 5/30/23 14:05, Vladimir Makarov wrote:
> The following patch fixes an LRA bug triggered by switching H8300 target 
> from reload to LRA.  The description of the problem is in the commit 
> message.
> 
> The patch was successfully bootstrapped and tested on x86-64, aarch64, 
> and ppc64le.
THanks.  We should have H8 test data with this patch and LRA enabled 
about this time tomorrow.

Jeff
diff mbox series

Patch

diff --git a/gcc/lra-eliminations.cc b/gcc/lra-eliminations.cc
index 42206366669..68225339cb6 100644
--- a/gcc/lra-eliminations.cc
+++ b/gcc/lra-eliminations.cc
@@ -1308,6 +1308,16 @@  init_elimination (void)
   setup_elimination_map ();
 }
 
+/* Update and return stack pointer OFFSET after processing X.  */
+poly_int64
+lra_update_sp_offset (rtx x, poly_int64 offset)
+{
+  curr_sp_change = offset;
+  mark_not_eliminable (x, VOIDmode);
+  return curr_sp_change;
+}
+
+
 /* Eliminate hard reg given by its location LOC.  */
 void
 lra_eliminate_reg_if_possible (rtx *loc)
diff --git a/gcc/lra-int.h b/gcc/lra-int.h
index a400a0f85e2..4dbe6672f3a 100644
--- a/gcc/lra-int.h
+++ b/gcc/lra-int.h
@@ -412,6 +412,7 @@  extern rtx lra_eliminate_regs_1 (rtx_insn *, rtx, machine_mode,
 extern void eliminate_regs_in_insn (rtx_insn *insn, bool, bool, poly_int64);
 extern void lra_eliminate (bool, bool);
 
+extern poly_int64 lra_update_sp_offset (rtx, poly_int64);
 extern void lra_eliminate_reg_if_possible (rtx *);
 
 
diff --git a/gcc/lra.cc b/gcc/lra.cc
index eb3ee1f8b63..c8b3f139acd 100644
--- a/gcc/lra.cc
+++ b/gcc/lra.cc
@@ -1838,10 +1838,10 @@  push_insns (rtx_insn *from, rtx_insn *to)
       lra_push_insn (insn);
 }
 
-/* Set up sp offset for insn in range [FROM, LAST].  The offset is
+/* Set up and return sp offset for insns in range [FROM, LAST].  The offset is
    taken from the next BB insn after LAST or zero if there in such
    insn.  */
-static void
+static poly_int64
 setup_sp_offset (rtx_insn *from, rtx_insn *last)
 {
   rtx_insn *before = next_nonnote_nondebug_insn_bb (last);
@@ -1849,7 +1849,11 @@  setup_sp_offset (rtx_insn *from, rtx_insn *last)
 		       ? 0 : lra_get_insn_recog_data (before)->sp_offset);
 
   for (rtx_insn *insn = from; insn != NEXT_INSN (last); insn = NEXT_INSN (insn))
-    lra_get_insn_recog_data (insn)->sp_offset = offset;
+    {
+      lra_get_insn_recog_data (insn)->sp_offset = offset;
+      offset = lra_update_sp_offset (PATTERN (insn), offset);
+    }
+  return offset;
 }
 
 /* Emit insns BEFORE before INSN and insns AFTER after INSN.  Put the
@@ -1875,8 +1879,25 @@  lra_process_new_insns (rtx_insn *insn, rtx_insn *before, rtx_insn *after,
       if (cfun->can_throw_non_call_exceptions)
 	copy_reg_eh_region_note_forward (insn, before, NULL);
       emit_insn_before (before, insn);
+      poly_int64 old_sp_offset = lra_get_insn_recog_data (insn)->sp_offset;
+      poly_int64 new_sp_offset = setup_sp_offset (before, PREV_INSN (insn));
+      if (maybe_ne (old_sp_offset, new_sp_offset))
+	{
+	  if (lra_dump_file != NULL)
+	    {
+	      fprintf (lra_dump_file, "    Changing sp offset from ");
+	      print_dec (old_sp_offset, lra_dump_file);
+	      fprintf (lra_dump_file, " to ");
+	      print_dec (new_sp_offset, lra_dump_file);
+	      fprintf (lra_dump_file, " for insn");
+	      dump_rtl_slim (lra_dump_file, insn, NULL, -1, 0);
+	    }
+	  lra_get_insn_recog_data (insn)->sp_offset = new_sp_offset;
+	  eliminate_regs_in_insn (insn, false, false,
+				  old_sp_offset - new_sp_offset);
+	  lra_push_insn (insn);
+	}
       push_insns (PREV_INSN (insn), PREV_INSN (before));
-      setup_sp_offset (before, PREV_INSN (insn));
     }
   if (after != NULL_RTX)
     {