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  <ja...@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.

--- 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;
+    }
+}


        Jakub

Reply via email to