https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110587
--- Comment #10 from Richard Biener <rguenth at gcc dot gnu.org> --- I wonder what the following does anyway. We delete the noop move only when either the reg isn't used for return or it isn't in use in later insns between 'insn' and the next set of it. That seems to detect the hardreg = X; USE (hardreg); return sequence and wants to protect that despite X being the same as 'hardreg'. /* IRA can generate move insns involving pseudos. It is better remove them earlier to speed up compiler a bit. It is also better to do it here as they might not pass final RTL check in LRA, (e.g. insn moving a control register into itself). So remove an useless move insn unless next insn is USE marking the return reg (we should save this as some subsequent optimizations assume that such original insns are saved). */ if (NONJUMP_INSN_P (insn) && GET_CODE (pat) == SET && REG_P (SET_SRC (pat)) && REG_P (SET_DEST (pat)) && REGNO (SET_SRC (pat)) == REGNO (SET_DEST (pat)) && (! return_regno_p (REGNO (SET_SRC (pat))) || ! regno_in_use_p (insn, REGNO (SET_SRC (pat))))) what's odd is of course that return_regno_p returns true so much for this testcase. The return sequence to protect should be easily discoverable by walking from the function exit and thus could be marked instead of trying to match it to each insn like above. But I don't understand why we want to preserve this noop copy anyway ...