On 6/26/25 1:51 AM, Alexandre Oliva wrote:
On Jun 25, 2025, Vladimir Makarov <vmaka...@redhat.com> wrote:

This patch is ok for me.  I am a big fan of asserts. They helped to catch so many bugs on early stages.

Thank you, Alex.




for  gcc/ChangeLog

        PR rtl-optimization/120424
        * lra-eliminations.cc (elimination_2sp_occurred_p): Rename
        from...
        (elimination_fp2sp_occured_p): ... this.  Adjust all uses.
        (lra_eliminate_regs_1): Don't require a from-frame-pointer
        elimination to set it.
        (update_reg_eliminate): Likewise to test it.
---
  gcc/lra-eliminations.cc |   46 +++++++++++++++++++++++++---------------------
  1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/gcc/lra-eliminations.cc b/gcc/lra-eliminations.cc
index 9cdd0c5ff53a2..045f2dcf23ef7 100644
--- a/gcc/lra-eliminations.cc
+++ b/gcc/lra-eliminations.cc
@@ -309,8 +309,18 @@ move_plus_up (rtx x)
    return x;
  }
-/* Flag that we already did frame pointer to stack pointer elimination. */
-static bool elimination_fp2sp_occured_p = false;
+/* Flag that we already applied nonzero stack pointer elimination
+   offset; such sp updates cannot currently be undone.  */
+static bool elimination_2sp_occurred_p = false;
+
+/* Take note of any nonzero sp-OFFSET used in eliminations to sp.  */
+static inline poly_int64
+note_spoff (poly_int64 offset)
+{
+  if (maybe_ne (offset, 0))
+    elimination_2sp_occurred_p = true;
+  return offset;
+}
/* Scan X and replace any eliminable registers (such as fp) with a
     replacement (such as sp) if SUBST_P, plus an offset.  The offset is
@@ -369,13 +379,10 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode 
mem_mode,
        {
          rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
- if (ep->to_rtx == stack_pointer_rtx && ep->from == FRAME_POINTER_REGNUM)
-           elimination_fp2sp_occured_p = true;
-
          if (maybe_ne (update_sp_offset, 0))
            {
              if (ep->to_rtx == stack_pointer_rtx)
-               return plus_constant (Pmode, to, update_sp_offset);
+               return plus_constant (Pmode, to, note_spoff (update_sp_offset));
              return to;
            }
          else if (update_p)
@@ -385,7 +392,8 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode 
mem_mode,
                                  ep->offset
                                  - (insn != NULL_RTX
                                     && ep->to_rtx == stack_pointer_rtx
-                                    ? lra_get_insn_recog_data (insn)->sp_offset
+                                    ? note_spoff (lra_get_insn_recog_data
+                                                  (insn)->sp_offset)
                                     : 0));
          else
            return to;
@@ -402,19 +410,18 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode 
mem_mode,
              poly_int64 offset, curr_offset;
              rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
- if (ep->to_rtx == stack_pointer_rtx && ep->from == FRAME_POINTER_REGNUM)
-               elimination_fp2sp_occured_p = true;
-
              if (! update_p && ! full_p)
                return simplify_gen_binary (PLUS, Pmode, to, XEXP (x, 1));
if (maybe_ne (update_sp_offset, 0))
-               offset = ep->to_rtx == stack_pointer_rtx ? update_sp_offset : 0;
+               offset = (ep->to_rtx == stack_pointer_rtx
+                         ? note_spoff (update_sp_offset)
+                         : 0);
              else
                offset = (update_p
                          ? ep->offset - ep->previous_offset : ep->offset);
              if (full_p && insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx)
-               offset -= lra_get_insn_recog_data (insn)->sp_offset;
+               offset -= note_spoff (lra_get_insn_recog_data 
(insn)->sp_offset);
              if (poly_int_rtx_p (XEXP (x, 1), &curr_offset)
                  && known_eq (curr_offset, -offset))
                return to;
@@ -465,15 +472,13 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode 
mem_mode,
        {
          rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
- if (ep->to_rtx == stack_pointer_rtx && ep->from == FRAME_POINTER_REGNUM)
-           elimination_fp2sp_occured_p = true;
-
          if (maybe_ne (update_sp_offset, 0))
            {
              if (ep->to_rtx == stack_pointer_rtx)
                return plus_constant (Pmode,
                                      gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
-                                     update_sp_offset * INTVAL (XEXP (x, 1)));
+                                     note_spoff (update_sp_offset)
+                                     * INTVAL (XEXP (x, 1)));
              return gen_rtx_MULT (Pmode, to, XEXP (x, 1));
            }
          else if (update_p)
@@ -486,7 +491,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode 
mem_mode,
              poly_int64 offset = ep->offset;
if (insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx)
-               offset -= lra_get_insn_recog_data (insn)->sp_offset;
+               offset -= note_spoff (lra_get_insn_recog_data 
(insn)->sp_offset);
              return
                plus_constant (Pmode,
                               gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
@@ -1213,8 +1218,7 @@ update_reg_eliminate (bitmap insns_with_changed_offsets)
             pointer elimination the condition is a bit relaxed and we just 
require
             that actual elimination has not been done yet.   */
          gcc_assert (ep->to_rtx != stack_pointer_rtx
-                     || (ep->from == FRAME_POINTER_REGNUM
-                         && !elimination_fp2sp_occured_p)
+                     || !elimination_2sp_occurred_p
                      || (ep->from < FIRST_PSEUDO_REGISTER
                          && fixed_regs [ep->from]));
@@ -1429,7 +1433,7 @@ lra_update_fp2sp_elimination (int *spilled_pseudos) if (frame_pointer_needed || !targetm.frame_pointer_required ())
      return 0;
-  gcc_assert (!elimination_fp2sp_occured_p);
+  gcc_assert (!elimination_2sp_occurred_p);
    ep = elimination_map[FRAME_POINTER_REGNUM];
    if (ep->to == STACK_POINTER_REGNUM)
      {
@@ -1499,7 +1503,7 @@ lra_eliminate (bool final_p, bool first_p)
if (first_p)
      {
-      elimination_fp2sp_occured_p = false;
+      elimination_2sp_occurred_p = false;
        init_elimination ();
      }

[TESTING] [lra] [x86] require frame pointer on nonzero frame size [PR120424]

FTR, this is what I used to test the above.

diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 84081ab126705..31e0f8a453de9 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -6035,6 +6035,11 @@ ix86_frame_pointer_required (void)
    if (crtl->profile && !flag_fentry)
      return true;
+ /* Exercise lra_update_fp2sp_elimination.
+     Requires -maccumulate-outgoing-args.  */
+  if (ix86_get_frame_size ())
+    return true;
+
    return false;
  }


Reply via email to