On Tue, Nov 27, 2012 at 5:57 PM, Eric Botcazou <ebotca...@adacore.com> wrote: >> This note seems very very weird. For one thing, it becomes invalid on >> the very instruction where it is created. I would say that it should >> not be there. > > Agreed.
Count me in, too. So let's avoid it: * gcse.c (struct reg_use): Remove unused struct. (gcse_emit_move_after): Do not create REG_EQUAL notes that reference the SET_DEST of the instruction the note would be attached to. Index: gcse.c =================================================================== --- gcse.c (revision 193394) +++ gcse.c (working copy) @@ -258,8 +258,6 @@ int flag_rerun_cse_after_global_opts; /* An obstack for our working variables. */ static struct obstack gcse_obstack; -struct reg_use {rtx reg_rtx; }; - /* Hash table of expressions. */ struct expr @@ -2482,23 +2480,27 @@ gcse_emit_move_after (rtx dest, rtx src, rtx new_rtx; rtx set = single_set (insn), set2; rtx note; - rtx eqv; + rtx eqv = NULL_RTX; /* This should never fail since we're creating a reg->reg copy we've verified to be valid. */ new_rtx = emit_insn_after (gen_move_insn (dest, src), insn); - /* Note the equivalence for local CSE pass. */ + /* Note the equivalence for local CSE pass. Take the note from the old + set if there was one. Otherwise record the SET_SRC from the old set + unless DEST is also an operand of the SET_SRC. */ set2 = single_set (new_rtx); if (!set2 || !rtx_equal_p (SET_DEST (set2), dest)) return new_rtx; if ((note = find_reg_equal_equiv_note (insn))) eqv = XEXP (note, 0); - else + else if (! REG_P (dest) + || ! reg_mentioned_p (dest, SET_SRC (set))) eqv = SET_SRC (set); - set_unique_reg_note (new_rtx, REG_EQUAL, copy_insn_1 (eqv)); + if (eqv != NULL_RTX) + set_unique_reg_note (new_rtx, REG_EQUAL, copy_insn_1 (eqv)); return new_rtx; } And perhaps a bit in emit-rtl.c for good measure? I'll see if/where this causes breakage... Index: emit-rtl.c =================================================================== --- emit-rtl.c (revision 193394) +++ emit-rtl.c (working copy) @@ -4932,6 +4932,19 @@ gen_use (rtx x) return seq; } +/* Return true if DATUM has a USE of the SET_DEST of INSN. */ +static bool +self_ref_note_p (rtx insn, rtx datum) +{ + rtx set = single_set (insn); + if (! set) + return false; + rtx dest = SET_DEST (set); + if (! REG_P (dest)) + return false; + return reg_mentioned_p (dest, datum); +} + /* Place a note of KIND on insn INSN with DATUM as the datum. If a note of this type already exists, remove it first. */ @@ -4961,6 +4974,8 @@ set_unique_reg_note (rtx insn, enum reg_ if (note) { + if (self_ref_note_p (insn, datum)) + internal_error ("self-reference in REG_EQUAL or REG_EQUIV note!\n"); XEXP (note, 0) = datum; df_notes_rescan (insn); return note; @@ -4982,6 +4997,8 @@ set_unique_reg_note (rtx insn, enum reg_ { case REG_EQUAL: case REG_EQUIV: + if (self_ref_note_p (insn, datum)) + internal_error ("self-reference in REG_EQUAL or REG_EQUIV note!\n"); df_notes_rescan (insn); break; default: