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