Hi! DEBUG_INSN with LABEL_DECL var isn't duplicated in bb copies (we want just one definition of the label), which breaks apply_opt_in_copies attempt to match insn in bb copy with orig_insn from the orig_bb.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2011-11-28 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/51014 * loop-unroll.c (apply_opt_in_copies): Ignore label DEBUG_INSNs both from bb and orig_bb. * g++.dg/opt/pr51014.C: New test. --- gcc/loop-unroll.c.jj 2011-02-15 15:42:26.000000000 +0100 +++ gcc/loop-unroll.c 2011-11-28 21:03:58.089497366 +0100 @@ -2262,10 +2262,15 @@ apply_opt_in_copies (struct opt_info *op for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb)); insn = next) { next = NEXT_INSN (insn); - if (!INSN_P (insn)) + if (!INSN_P (insn) + || (DEBUG_INSN_P (insn) + && TREE_CODE (INSN_VAR_LOCATION_DECL (insn)) == LABEL_DECL)) continue; - while (!INSN_P (orig_insn)) + while (!INSN_P (orig_insn) + || (DEBUG_INSN_P (orig_insn) + && (TREE_CODE (INSN_VAR_LOCATION_DECL (orig_insn)) + == LABEL_DECL))) orig_insn = NEXT_INSN (orig_insn); ivts_templ.insn = orig_insn; --- gcc/testsuite/g++.dg/opt/pr51014.C.jj 2011-11-28 21:08:19.518986308 +0100 +++ gcc/testsuite/g++.dg/opt/pr51014.C 2011-11-28 21:07:24.000000000 +0100 @@ -0,0 +1,16 @@ +// PR rtl-optimization/51014 +// { dg-do compile } +// { dg-options "-O2 -funroll-loops -fcompare-debug" } + +struct S +{ + ~S() { delete s; } + int *s; +}; + +void +f (S *x, S *y) +{ + for (; x != y; ++x) + x->~S(); +} Jakub