PR70890, stage2 miscompilation
authorAlan Modra <amodra@gmail.com>
Tue, 3 May 2016 14:43:35 +0000 (00:13 +0930)
committerAlan Modra <amodra@gcc.gnu.org>
Tue, 3 May 2016 14:43:35 +0000 (00:13 +0930)
PR rtl-optimization/70890
* ira.c (combine_and_move_insns): When moving def_insn, remove
equivs on use_insn.

From-SVN: r235825

gcc/ChangeLog
gcc/ira.c

index 095e502adfa4a47adba6f01c293946bf64944550..7cd0bd4f73de1033539dc13b9e40d5b628c0db88 100644 (file)
@@ -1,3 +1,9 @@
+2016-05-03  Alan Modra  <amodra@gmail.com>
+
+       PR rtl-optimization/70890
+       * ira.c (combine_and_move_insns): When moving def_insn, remove
+       equivs on use_insn.
+
 2016-05-03  Dominik Vogt  <vogt@linux.vnet.ibm.com>
 
        * config/s390/s390.md ("*r<noxa>sbg_<mode>_sll")
index d383a5513705e3447d26c64ea7343e607425ea7f..55b4bd700be81dd9d7b5644db66ddec65a31da6c 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -3742,6 +3742,22 @@ combine_and_move_insns (void)
          if (use_insn == BB_HEAD (use_bb))
            BB_HEAD (use_bb) = new_insn;
 
+         /* We know regno dies in use_insn, but inside a loop
+            REG_DEAD notes might be missing when def_insn was in
+            another basic block.  However, when we move def_insn into
+            this bb we'll definitely get a REG_DEAD note and reload
+            will see the death.  It's possible that update_equiv_regs
+            set up an equivalence referencing regno for a reg set by
+            use_insn, when regno was seen as non-local.  Now that
+            regno is local to this block, and dies, such an
+            equivalence is invalid.  */
+         if (find_reg_note (use_insn, REG_EQUIV, NULL_RTX))
+           {
+             rtx set = single_set (use_insn);
+             if (set && REG_P (SET_DEST (set)))
+               no_equiv (SET_DEST (set), set, NULL);
+           }
+
          ira_reg_equiv[regno].init_insns
            = gen_rtx_INSN_LIST (VOIDmode, new_insn, NULL_RTX);
          bitmap_set_bit (cleared_regs, regno);