diff mbox

Fix twolf -funroll-loops -O3 miscompilation (a semi-latent web.c bug)

Message ID CABu31nMq+J7mQygwTrNTGLsQ_CyTaFHnHpaxS01s+++nqzdbbg@mail.gmail.com
State New
Headers show

Commit Message

Steven Bosscher Dec. 3, 2012, 11:27 p.m. UTC
On Mon, Dec 3, 2012 at 9:19 PM, Steven Bosscher wrote:
>> So the compiler doesn't bootstrap with the gcse.c patch you posted earlier in
>> the thread?  Still this seems too bold to me, the note datum could be a
>> constant and should be preserved in this case.
>
> You mean the patch at
> http://gcc.gnu.org/ml/gcc-patches/2012-11/msg02275.html right?
>
> I haven't tried that other patch. I'll test that one.
>
...
>> The cse.c hunk is OK then.
>
> Thanks, I'll commit it separately.

This is what I'll commit in a second.
A new proposed cprop.c change will follow later.

Ciao!
Steven


        * 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.
        * cse.c (cse_main): Add the DF_NOTE problem.
diff mbox

Patch

Index: gcse.c
===================================================================
--- gcse.c      (revision 194084)
+++ gcse.c      (working copy)
@@ -255,8 +255,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
@@ -2491,23 +2489,27 @@  gcse_emit_move_after (rtx dest, rtx src, rtx insn)
   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;
 }
Index: cse.c
===================================================================
--- cse.c       (revision 194084)
+++ cse.c       (working copy)
@@ -6520,6 +6520,7 @@  cse_main (rtx f ATTRIBUTE_UNUSED, int nregs)
   int i, n_blocks;

   df_set_flags (DF_LR_RUN_DCE);
+  df_note_add_problem ();
   df_analyze ();
   df_set_flags (DF_DEFER_INSN_RESCAN);