On 11/10/11 13:14, Richard Guenther wrote:
> Fair enough.  You can count me as "one" then, and I'll defer to Bernd
> to either provide a fix or ack the revert.

I'm trying to track it down.

In 189r.outof_cfglayout, we have

(insn 31 33 35 3 (use (reg/i:SI 0 r0))
../../../../baseline-trunk/libstdc++-v3/libsupc++/new_opv.cc:34 -1
     (nil))

;; Successors:  EXIT [100.0%]  (fallthru)
;; lr  out       0 [r0] 11 [fp] 13 [sp] 14 [lr] 25 [sfp] 26 [afp]
;; live  out     0 [r0] 11 [fp] 13 [sp] 25 [sfp] 26 [afp]

followed by a number of other basic blocks, so that looks wrong to me.
outof_cfglayout seems to assume that fallthrough edges to the exit block
are OK and don't need fixing up, and changing that seems nontrivial at
first glance.

The situation is first created during cfgcleanup in into_cfglayout. The
following patch makes the testcase compile by stopping the compiler from
moving the exit fallthru block around, but I've not checked whether it
has a negative effect on code quality. HP, can you run full tests?


Bernd
Index: ../baseline-trunk/gcc/cfgrtl.c
===================================================================
--- ../baseline-trunk/gcc/cfgrtl.c      (revision 181252)
+++ ../baseline-trunk/gcc/cfgrtl.c      (working copy)
@@ -2735,6 +2735,16 @@ cfg_layout_can_merge_blocks_p (basic_blo
   if (BB_PARTITION (a) != BB_PARTITION (b))
     return false;
 
+  /* If we would end up moving B's instructions, make sure it doesn't fall
+     through into the exit block, since we cannot recover from a fallthrough
+     edge into the exit block occurring in the middle of a function.  */
+  if (NEXT_INSN (BB_END (a)) != BB_HEAD (b))
+    {
+      edge e = find_fallthru_edge (b->succs);
+      if (e && e->dest == EXIT_BLOCK_PTR)
+       return false;
+    }
+
   /* There must be exactly one edge in between the blocks.  */
   return (single_succ_p (a)
          && single_succ (a) == b

Reply via email to