diff mbox

Fix PR rtl-optimization/44469

Message ID 201101262211.53171.ebotcazou@adacore.com
State New
Headers show

Commit Message

Eric Botcazou Jan. 26, 2011, 9:11 p.m. UTC
This is a regression present on the mainline and 4.5 branch for the ARM.  The 
compiler aborts at -O2 during basic block reordering pass on code involving  
__builtin_unreachable () because of a dangling conditional jump.

As diagnosed by Jakub, the problem is that, while cleanup_cfg removes an empty 
block present right before the barrier generated for __builtin_unreachable, 
it doesn't turn the conditional jump that jumps to it into an unconditional 
jump to the other branch.

Now try_optimize_cfg already knows to do that; the problem is only that it 
fails to iterate after removing the empty block because of these lines:

		  delete_basic_block (b);
		  if (!(mode & CLEANUP_CFGLAYOUT))
		    changed = true;

In CFG layout mode, deleting the block isn't recognized as changing something.
The reasons for this are unclear, the line dates back to the introduction of 
the CFG layout mode in 2003; no comment, not even a mention in the ChangeLog.

The context was actually different, there was originally a loop there.  So I 
think that they are very likely obsolete by now and can be safely altered.

Bootstrapped/regtested on x86_64-suse-linux, applied on the mainline and 4.5 
branch.


2011-01-26  Eric Botcazou  <ebotcazou@adacore.com>

	PR rtl-optimization/44469
	* cfgcleanup.c (try_optimize_cfg): Iterate in CFG layout mode too
	after removing trivially dead basic blocks.


2011-01-26  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.c-torture/compile/20110126-1.c: New test.
diff mbox

Patch

Index: cfgcleanup.c
===================================================================
--- cfgcleanup.c	(revision 169285)
+++ cfgcleanup.c	(working copy)
@@ -2341,8 +2341,7 @@  try_optimize_cfg (int mode)
 			}
 		    }
 		  delete_basic_block (b);
-		  if (!(mode & CLEANUP_CFGLAYOUT))
-		    changed = true;
+		  changed = true;
 		  /* Avoid trying to remove ENTRY_BLOCK_PTR.  */
 		  b = (c == ENTRY_BLOCK_PTR ? c->next_bb : c);
 		  continue;