This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Fix twolf -funroll-loops -O3 miscompilation (a semi-latent web.c bug)
On Tue, Nov 27, 2012 at 5:57 PM, Eric Botcazou <ebotcazou@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: