On May 27, 2025, Vladimir Makarov <vmaka...@redhat.com> wrote: > This is a good explanation of the patch and the bug and the affected > code seem very old (from the first commit of LRA). So thank you very > much for working on and fixing this PR.
Thanks for the review. Jeff points out gcc.target/avr/torture/pr118591-1.c now fails to compile at all nonzero optimization levels on avr-none. The problem seems to be that, even after fp2sp is disabled, but before update_reg_eliminate gets a chance to run again, we spill some more pseudos and end up using the fp2sp elimination. I noticed that while investigating PR120424, and I had the patchlet below at some point, but I ended up concluding that it was not necessary, because the eliminations are reversible, and I figured that stopping applying them half-way would make for trouble reversing them. This tweak avoids the problem, but it's probably not the way to go for the reasons above. diff --git a/gcc/lra-eliminations.cc b/gcc/lra-eliminations.cc index bb708b007a4..36c5365f818 100644 --- a/gcc/lra-eliminations.cc +++ b/gcc/lra-eliminations.cc @@ -263,7 +263,7 @@ get_elimination (rtx reg) if ((hard_regno = REGNO (reg)) < 0 || hard_regno >= FIRST_PSEUDO_REGISTER) return NULL; if ((ep = elimination_map[hard_regno]) != NULL) - return ep->from_rtx != reg ? NULL : ep; + return ep->from_rtx != reg || !ep->can_eliminate ? NULL : ep; poly_int64 offset = self_elim_offsets[hard_regno]; if (known_eq (offset, 0)) return NULL; Now, since lra_update_fp2sp_elimination checks that !elimination_fp2sp_occured_p, we *could* disable the fp2sp elimination, if it's selected, right away, so that it is not applied after we've disabled it, and then we don't have to worry about disabling it half-way or reversing it later. Like the patchlet above, the one below also cures the avr regression. Does this strike you as the way to go, or can you envision better ways to approach this? --- a/gcc/lra-eliminations.cc +++ b/gcc/lra-eliminations.cc @@ -1415,6 +1415,14 @@ 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 @@ 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 < ®_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 < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) + if (ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM) + setup_can_eliminate (ep, false); return n; } -- Alexandre Oliva, happy hacker https://blog.lx.oliva.nom.br/ Free Software Activist FSFLA co-founder GNU Toolchain Engineer More tolerance and less prejudice are key for inclusion and diversity. Excluding neuro-others for not behaving ""normal"" is *not* inclusive!