The following fixes a fixup for loops when merging two basic-blocks.
We didn't handle merging two loop headers well which the following
patch addresses.

LTO bootstrapped (which was broken before this patch) and tested
on x86_64-unknown-linux-gnu, applied.

Richard.

2012-12-20  Richard Biener  <rguent...@suse.de>

        PR middle-end/55740
        * cfghooks.c (merge_blocks): Properly handle merging of
        two loop headers.

        * g++.dg/torture/pr55740.C: New testcase.

Index: gcc/cfghooks.c
===================================================================
*** gcc/cfghooks.c      (revision 194610)
--- gcc/cfghooks.c      (working copy)
*************** merge_blocks (basic_block a, basic_block
*** 724,734 ****
  
    cfg_hooks->merge_blocks (a, b);
  
-   /* If we merge a loop header into its predecessor, update the loop
-      structure.  */
    if (current_loops != NULL)
      {
!       if (b->loop_father->header == b)
        {
          remove_bb_from_loops (a);
          add_bb_to_loop  (a, b->loop_father);
--- 724,746 ----
  
    cfg_hooks->merge_blocks (a, b);
  
    if (current_loops != NULL)
      {
!       /* If the block we merge into is a loop header do nothing unless ... */
!       if (a->loop_father->header == a)
!       {
!         /* ... we merge two loop headers, in which case we kill
!            the inner loop.  */
!         if (b->loop_father->header == b)
!           {
!             b->loop_father->header = NULL;
!             b->loop_father->latch = NULL;
!             loops_state_set (LOOPS_NEED_FIXUP);
!           }
!       }
!       /* If we merge a loop header into its predecessor, update the loop
!        structure.  */
!       else if (b->loop_father->header == b)
        {
          remove_bb_from_loops (a);
          add_bb_to_loop  (a, b->loop_father);
Index: gcc/testsuite/g++.dg/torture/pr55740.C
===================================================================
*** gcc/testsuite/g++.dg/torture/pr55740.C      (revision 0)
--- gcc/testsuite/g++.dg/torture/pr55740.C      (working copy)
***************
*** 0 ****
--- 1,19 ----
+ // { dg-do compile }
+ 
+ static bool st_IsPathDelimiter( char c ) { return c == '/'; }
+ bool IsValidPath( char const * filename )
+ {
+   if ( !filename || filename[0] == 0 )     
+     return false;
+   char const * run = filename;
+   while ( run && *run )       
+     {
+       if ( run[0] == '.' )   
+       if ( run[1] != '.' || ( !st_IsPathDelimiter( run[2] ) && run[2] != 0 ) 
)   
+         return false;   
+       while ( *run && !st_IsPathDelimiter( *run ) )
+       ++run;
+       if ( *run ) 
+       ++run;
+     }
+ }

Reply via email to