Hi!

This patch fixes a RTL sharing issue, if *reg_equiv[REGNO (loc)].src_p
is e.g. a MEM and the cleared reg would be used in more than one
DEBUG_INSN or more than once in a single one, we'd incorrectly share it,
which can result e.g. in DF verification issue - change of one DEBUG_INSN
with the shared MEM results in a df insn rescan, but on the other DEBUG_INSN
no changes would be performed and thus rescanning wouldn't be performed.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk as obvious.

2014-03-20  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/60597
        * ira.c (adjust_cleared_regs): Call copy_rtx on
        *reg_equiv[REGNO (loc)].src_p before passing it to
        simplify_replace_fn_rtx.

        * g++.dg/opt/pr60597.C: New test.

--- gcc/ira.c.jj        2014-01-25 00:16:53.000000000 +0100
+++ gcc/ira.c   2014-03-20 16:35:11.881516283 +0100
@@ -3428,7 +3428,7 @@ adjust_cleared_regs (rtx loc, const_rtx
     {
       bitmap cleared_regs = (bitmap) data;
       if (bitmap_bit_p (cleared_regs, REGNO (loc)))
-       return simplify_replace_fn_rtx (*reg_equiv[REGNO (loc)].src_p,
+       return simplify_replace_fn_rtx (copy_rtx (*reg_equiv[REGNO 
(loc)].src_p),
                                        NULL_RTX, adjust_cleared_regs, data);
     }
   return NULL_RTX;
--- gcc/testsuite/g++.dg/opt/pr60597.C.jj       2014-03-20 16:34:40.915677263 
+0100
+++ gcc/testsuite/g++.dg/opt/pr60597.C  2014-03-20 16:34:21.000000000 +0100
@@ -0,0 +1,46 @@
+// PR middle-end/60597
+// { dg-do compile }
+// { dg-options "-O2 -g" }
+
+struct A
+{
+  int foo () const;
+  int bar () const;
+  int a;
+};
+
+struct B
+{
+  int foo ();
+  int bar ();
+};
+
+int *c, d;
+
+int
+A::foo () const
+{
+  int b = a >> 16;
+  return b;
+}
+
+int
+A::bar () const
+{
+  int b = a;
+  return b;
+}
+
+void
+baz (A &x, B h, int i, int j)
+{
+  for (; i < h.bar (); ++i)
+    for (; h.foo (); ++j)
+      {
+       int g = x.foo ();
+       int f = x.bar ();
+       int e = c[0] & 1;
+       d = (e << 1) | (g << 16) | (f & 1);
+       c[j] = 0;
+      }
+}

        Jakub

Reply via email to