Hi,
When I investigating PR60363 which is caused by previous patch for PR60280,
I found there is a latent bug in remove_forwarder_block_with_phi because GCC
doesn't update loop's latch information.  Without this patch, cfgcleanup
facility will remove and rebuild the loop structure, resulting in loss of
loop meta information.

This patch is just an obvious pickup, but it isn't intended to fix pr60363.

Test on cortex-m3
Bootstrap and test on x86_64

Is it OK?


2014-03-10  Bin Cheng  <bin.ch...@arm.com>

        * tree-cfgcleanup.c (remove_forwarder_block_with_phi): Record
        bb's single pred and update the father loop's latch info later.
Index: gcc/tree-cfgcleanup.c
===================================================================
--- gcc/tree-cfgcleanup.c       (revision 208447)
+++ gcc/tree-cfgcleanup.c       (working copy)
@@ -820,6 +820,12 @@ remove_forwarder_block_with_phi (basic_block bb)
       && DECL_NONLOCAL (gimple_label_label (label)))
     return false;
 
+  /* Record bb's single pred in case we need to update the father
+     loop's latch information later.  */
+  basic_block pred = NULL;
+  if (single_pred_p (bb))
+    pred = single_pred (bb);
+
   /* Redirect each incoming edge to BB to DEST.  */
   while (EDGE_COUNT (bb->preds) > 0)
     {
@@ -904,6 +910,11 @@ remove_forwarder_block_with_phi (basic_block bb)
 
   set_immediate_dominator (CDI_DOMINATORS, dest, dom);
 
+  /* Adjust latch infomation of BB's parent loop as otherwise
+     the cfg hook has a hard time not to kill the loop.  */
+  if (current_loops && bb->loop_father->latch == bb)
+    bb->loop_father->latch = pred;
+
   /* Remove BB since all of BB's incoming edges have been redirected
      to DEST.  */
   delete_basic_block (bb);

Reply via email to