[PATCH] Handle inter-block notes before BARRIER in rtl merge_blocks (PR target/69175)
Jakub Jelinek
jakub@redhat.com
Fri Jan 8 20:17:00 GMT 2016
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 <jakub@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
More information about the Gcc-patches
mailing list