[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