Hi! As mentioned in the PR, sched1 and reload add NOTE_INSN_DELETED notes that are moved by shrink-wrapping in between some basic blocks and later on we end up with a barrier after the notes. From comments above cleanup_barriers pass I think it isnot invalid, and various other places deal with notes before barrier, so this patch teaches rtl_merge_block to deal with that too.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Independently, it would be nice if sched and reload clean those NOTE_INSN_DELETED after themselves, there should be no reason why those should be hanging around until final. 2016-01-08 Jakub Jelinek <ja...@redhat.com> PR target/69175 * cfgrtl.c (rtl_merge_blocks): Look for BARRIER even after notes outside of basic block. * g++.dg/opt/pr69175.C: New test. --- gcc/cfgrtl.c.jj 2016-01-04 14:55:50.000000000 +0100 +++ gcc/cfgrtl.c 2016-01-08 12:57:00.973745865 +0100 @@ -875,8 +875,15 @@ rtl_merge_blocks (basic_block a, basic_b a_end = PREV_INSN (del_first); } - else if (BARRIER_P (NEXT_INSN (a_end))) - del_first = NEXT_INSN (a_end); + else + { + rtx_insn *end = NEXT_INSN (a_end); + while (end && NOTE_P (end) && !NOTE_INSN_BASIC_BLOCK_P (end)) + end = NEXT_INSN (end); + + if (end && BARRIER_P (end)) + del_first = end; + } /* Delete everything marked above as well as crap that might be hanging out between the two blocks. */ --- gcc/testsuite/g++.dg/opt/pr69175.C.jj 2016-01-08 13:04:04.084805432 +0100 +++ gcc/testsuite/g++.dg/opt/pr69175.C 2016-01-08 13:03:47.000000000 +0100 @@ -0,0 +1,29 @@ +// PR target/69175 +// { dg-do compile } +// { dg-options "-O2" } +// { dg-additional-options "-march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -mthumb" { target { arm_hard_vfp_ok && arm_thumb2_ok } } } + +struct A { A *c, *d; } a; +struct B { A *e; A *f; void foo (); }; +void *b; + +void +B::foo () +{ + if (b) + { + A *n = (A *) b; + if (b == e) + if (n == f) + e = __null; + else + e->c = __null; + else + n->d->c = &a; + n->d = e; + if (e == __null) + e = f = n; + else + e = n; + } +} Jakub