[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