http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47008
--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> 2010-12-20 13:03:56 UTC --- --- reload1.c.jj 2010-11-25 18:50:45.000000000 +0100 +++ reload1.c 2010-12-20 12:54:34.924901692 +0100 @@ -3597,9 +3597,20 @@ eliminate_regs_in_insn (rtx insn, int re of spill registers to be needed in the final reload pass than in the pre-passes. */ if (val && REG_NOTES (insn) != 0) - REG_NOTES (insn) - = eliminate_regs_1 (REG_NOTES (insn), VOIDmode, REG_NOTES (insn), true, - false); + { + rtx note; + REG_NOTES (insn) + = eliminate_regs_1 (REG_NOTES (insn), VOIDmode, REG_NOTES (insn), true, + false); + /* Register elimination might change a REG_EQUIV note expression from + something that is constant to e.g. stack pointer based expression, + which can't be safely moved across stack pointer adjustments. + Downgrade such notes to REG_EQUAL. */ + for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) + if (REG_NOTE_KIND (note) == REG_EQUIV + && rtx_varies_p (XEXP (note, 0), 0)) + PUT_REG_NOTE_KIND (note, REG_EQUAL); + } return val; } unfortunately doesn't fix this. --- postreload.c.jj 2010-12-02 13:15:24.000000000 +0100 +++ postreload.c 2010-12-20 14:01:23.404758077 +0100 @@ -1415,7 +1415,8 @@ reload_combine_note_store (rtx dst, cons { dst = XEXP (dst, 0); if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC - || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC) + || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC + || GET_CODE (dst) == PRE_MODIFY || GET_CODE (dst) == POST_MODIFY) { regno = REGNO (XEXP (dst, 0)); mode = GET_MODE (XEXP (dst, 0)); does though. Perhaps just the latter patch would be good enough, dunno whether something after reload ever makes a difference between REG_EQUIV and REG_EQUAL.