Message ID | 4EBBD1A0.3060101@codesourcery.com |
---|---|
State | New |
Headers | show |
On Thu, Nov 10, 2011 at 02:29:04PM +0100, Bernd Schmidt wrote: > 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? FWIW, I did bootstrap and make check with/without this patch, and it introduces no regressions in the PowerPC, but I haven't look at the code generated.
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