diff mbox

Handle inter-block notes before BARRIER in rtl merge_blocks (PR target/69175, take 2)

Message ID 20160112101732.GC3017@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Jan. 12, 2016, 10:17 a.m. UTC
On Sat, Jan 09, 2016 at 12:27:02AM +0100, Bernd Schmidt wrote:
> Well, I checked a bit more. Most callers of merge_blocks seem to already
> look for barriers if they are a concern and remove them. This occurs
> multiple times in ifcvt.c and cfgcleanup.c. Oddly,
> merge_blocks_move_predecessor_nojumps uses next_nonnote_insn to find the
> barrier, while merge_blocks_move_successor_nojumps uses just NEXT_INSN. That
> should probably be fixed too.
> 
> So the situation is a bit odd in that most callers remove the barrier but
> merge_blocks tries to handle an isolated barrier as well. The area could
> probably cleaned up a little, but on the whole I still lean towards
> requiring the caller to remove an isolated barrier. That leaves the RTL in a
> more consistent state before the call to merge_blocks.

So is the following ok for trunk?
Bootstrapped/regtested on x86_64-linux and i686-linux, and Kyrill has kindly
bootstrapped/regtested it on arm too.

2016-01-12  Jakub Jelinek  <jakub@redhat.com>

	PR target/69175
	* ifcvt.c (cond_exec_process_if_block): When removing the last
	insn from then_bb, remove also any possible barriers that follow it.

	* g++.dg/opt/pr69175.C: New test.



	Jakub

Comments

Bernd Schmidt Jan. 12, 2016, 12:24 p.m. UTC | #1
On 01/12/2016 11:17 AM, Jakub Jelinek wrote:
>
> 	PR target/69175
> 	* ifcvt.c (cond_exec_process_if_block): When removing the last
> 	insn from then_bb, remove also any possible barriers that follow it.
>
> 	* g++.dg/opt/pr69175.C: New test.

Ok.


Bernd
diff mbox

Patch

--- gcc/ifcvt.c.jj	2016-01-04 14:55:53.000000000 +0100
+++ gcc/ifcvt.c	2016-01-11 16:13:22.833174933 +0100
@@ -739,7 +739,7 @@  cond_exec_process_if_block (ce_if_block
       rtx_insn *from = then_first_tail;
       if (!INSN_P (from))
 	from = find_active_insn_after (then_bb, from);
-      delete_insn_chain (from, BB_END (then_bb), false);
+      delete_insn_chain (from, get_last_bb_insn (then_bb), false);
     }
   if (else_last_head)
     delete_insn_chain (first_active_insn (else_bb), else_last_head, false);
--- 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;
+    }
+}