For both testcases in the PR, reload fails to take into account that
FP-SP elimination can no longer be performed, and tries to find reload
regs for an rtx generated when FP-SP elimination was valid.
1. reload initializes elim table with FP->SP elimination enabled.
2. alter_reg for a pseudo allocates a stack slot for the pseudo, and sets
reg_equiv_memory_loc to frame_pointer_rtx plus offset. It also sets
something_was_spilled to true.
3. The main reload loop starts, and it resets something_was_spilled to false.
4. reload calls eliminate_regs for the pseudo and sets reg_equiv_address to
(mem(SP + offset)).
5. calculate_needs_all_insns pushes a reload for SP (for the AVR target,
SP cannot be a pointer reg - it needs to be reloaded into X Y or Z regs).
6. update_eliminables_and_spill calls targetm.frame_pointer_required,
which returns true. That causes can_eliminate for FP->SP to be reset
to zero, and FP to be added to bad_spill_regs_global. For the AVR,
FP is Y, one of the 3 pointer regs. reload also notes that something
has changed, and that the loop needs to run again.
7. reload still calls select_reload_regs, and find_regs fails to find a
pointer reg to reload SP, which is unnecessary as FP->SP elimination
had been disabled anyway in (6).
IOW, reload fails to find pointer regs for an RTL expression that was
created when FP->SP elimination was true, even after it turns out that
the elimination can't be done after all. The patch tries to detect that
- if it knows the loop is going to run again, it silences the failure.
Also note that at a different point in the loop, the reload loop starts
over if something_was_spilled (line 982-986). If set outside the reload
loop by alter_reg, it gets reset at (3) - not sure why. I'd think a
"continue" after update_eliminables_and_spill (line 1019-1022) would
also work - haven't tested it though.