http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47008
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |law at gcc dot gnu.org, | |vmakarov at gcc dot gnu.org --- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> 2010-12-20 11:10:00 UTC --- The note is added in update_equiv_regs called from ira. /* cse sometimes generates function invariants, but doesn't put a REG_EQUAL note on the insn. Since this note would be redundant, there's no point creating it earlier than here. */ if (! note && ! rtx_varies_p (src, 0)) note = set_unique_reg_note (insn, REG_EQUAL, copy_rtx (src)); ... /* If this register is known to be equal to a constant, record that it is always equivalent to the constant. */ if (DF_REG_DEF_COUNT (regno) == 1 && note && ! rtx_varies_p (XEXP (note, 0), 0)) { rtx note_value = XEXP (note, 0); remove_note (insn, note); set_unique_reg_note (insn, REG_EQUIV, note_value); } This is correct at that point, because note_value is frame - 48, which really is constant through the whole function. But when /* If we changed something, perform elimination in REG_NOTES. This is needed even when REPLACE is zero because a REG_DEAD note might refer to a register that we eliminate and could cause a different number 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); in eliminate_regs_in_insn changes the REG_EQUIV note content from frame - something to %rsp + something, the expression is suddenly not constant anymore. So, shouldn't eliminate_regs_1 here downgrade REG_EQUIV notes where !rtx_varies_p before and rtx_varies_p afterwards to REG_EQUAL?