[PATCH][RFC] Fix PR54824, deal with BBs with no successor
Richard Biener
rguenther@suse.de
Thu Oct 25 13:52:00 GMT 2012
On Thu, 25 Oct 2012, Richard Biener wrote:
> On Thu, 25 Oct 2012, Jakub Jelinek wrote:
>
> > On Thu, Oct 25, 2012 at 12:58:26PM +0200, Richard Biener wrote:
> > > So the bug here is really in find_many_sub_basic_blocks then
> > > and your patch would certainly avoid triggering its bug
> > > (or its wrong expectations). I'll give it testing.
> >
> > I'd say we should insert the __builtin_unreachable already far earlier than
> > that, either when inlining the noreturn function and figuring out
> > it might return (perhaps conditionally on something that never happens),
> > or if LTO does something similar with it even without inlining.
>
> That would be fixup_cfg which is supposed to deal with this kind of
> "fallout", like in my original patch (just using __builtin_unreachable ()
> instead of an infinite loop edge)
>
> Honza?
Like the following, bootstrap & regtest pending on
x86_64-unknown-linux-gnu.
Richard.
2012-10-15 Richard Biener <rguenther@suse.de>
PR middle-end/54824
* tree-optimize.c (execute_fixup_cfg): Insert __builtin_unreachable
at the end of blocks with no successors.
* gcc.dg/torture/pr54824.c: New testcase.
Index: gcc/tree-optimize.c
===================================================================
*** gcc/tree-optimize.c (revision 192803)
--- gcc/tree-optimize.c (working copy)
*************** execute_fixup_cfg (void)
*** 180,185 ****
--- 180,204 ----
FOR_EACH_EDGE (e, ei, bb->succs)
e->count = (e->count * count_scale
+ REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
+
+ /* If we have a basic-block with no successors that does not
+ end with a control statement or a noreturn call connect it
+ to itself. This situation can occur when inlining a noreturn
+ call that does in fact return. */
+ if (EDGE_COUNT (bb->succs) == 0)
+ {
+ gimple stmt = last_stmt (bb);
+ if (!stmt
+ || (!is_ctrl_stmt (stmt)
+ && (!is_gimple_call (stmt)
+ || (gimple_call_flags (stmt) & ECF_NORETURN) == 0)))
+ {
+ stmt = gimple_build_call
+ (builtin_decl_implicit (BUILT_IN_UNREACHABLE), 0);
+ gimple_stmt_iterator gsi = gsi_last_bb (bb);
+ gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
+ }
+ }
}
if (count_scale != REG_BR_PROB_BASE)
compute_function_frequency ();
Index: gcc/testsuite/gcc.dg/torture/pr54824.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr54824.c (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr54824.c (working copy)
***************
*** 0 ****
--- 1,16 ----
+ /* { dg-do compile } */
+ /* { dg-options "-w" } */
+
+ void __attribute__((noreturn)) bar(void)
+ {
+ }
+
+ void foo(int i, char *p, char *q)
+ {
+ while (*p++) {
+ if (i)
+ p++;
+ if (!*q++)
+ bar();
+ }
+ }
More information about the Gcc-patches
mailing list