https://gcc.gnu.org/g:577cc6d0fd2a0e400e70a1627a6baa06185eac17

commit 577cc6d0fd2a0e400e70a1627a6baa06185eac17
Author: Alexandre Oliva <ol...@adacore.com>
Date:   Fri Jun 6 02:03:31 2025 -0300

    [lra] inactivate disabled fp2sp elimination
    
    Even after we disable the fp2sp elimination when it is the active
    elimination for the fp, spilling might use it before
    update_reg_eliminate runs and inactivates it for good.  If it is used,
    update_reg_eliminate will fail the check that fp2sp was not used.
    
    Since we keep track of uses of this specific elimination, and
    lra_update_fp2sp_elimination checks it before disabling it, we know it
    hasn't been used, so we can inactivate it without any ill effects.
    
    This fixes the pr118591-1.c avr-none regression exposed by the
    PR120424 fix.
    
    
    for  gcc/ChangeLog
    
            * lra-eliminations.cc (lra_update_fp2sp_elimination):
            Inactivate the unused fp2sp elimination right away.

Diff:
---
 gcc/lra-eliminations.cc | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/gcc/lra-eliminations.cc b/gcc/lra-eliminations.cc
index bb708b007a4e..6c8c91086f32 100644
--- a/gcc/lra-eliminations.cc
+++ b/gcc/lra-eliminations.cc
@@ -1415,6 +1415,14 @@ lra_update_fp2sp_elimination (int *spilled_pseudos)
   if (frame_pointer_needed || !targetm.frame_pointer_required ())
     return 0;
   gcc_assert (!elimination_fp2sp_occured_p);
+  ep = elimination_map[FRAME_POINTER_REGNUM];
+  if (ep->to == STACK_POINTER_REGNUM)
+    {
+      elimination_map[FRAME_POINTER_REGNUM] = NULL;
+      setup_can_eliminate (ep, false);
+    }
+  else
+    ep = NULL;
   if (lra_dump_file != NULL)
     fprintf (lra_dump_file,
             "     Frame pointer can not be eliminated anymore\n");
@@ -1422,9 +1430,10 @@ lra_update_fp2sp_elimination (int *spilled_pseudos)
   CLEAR_HARD_REG_SET (set);
   add_to_hard_reg_set (&set, Pmode, HARD_FRAME_POINTER_REGNUM);
   n = spill_pseudos (set, spilled_pseudos);
-  for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
-    if (ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM)
-      setup_can_eliminate (ep, false);
+  if (!ep)
+    for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
+      if (ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM)
+       setup_can_eliminate (ep, false);
   return n;
 }

Reply via email to