Patchwork Fix PR rtl-optimization/46755

login
register
mail settings
Submitter Steven Bosscher
Date Dec. 17, 2010, 8:38 p.m.
Message ID <AANLkTikEW9LBVztMnOCj4zGR0550kiptuoVyKOp6m5g=@mail.gmail.com>
Download mbox | patch
Permalink /patch/75975/
State New
Headers show

Comments

Steven Bosscher - Dec. 17, 2010, 8:38 p.m.
Hello,

IRA is one of the last passes to recalculate jump labels. With
Fortran's ASSIGNed GOTO feature, we apparently can end up making
blocks unreachable this way (and probably a C test case can be
constructed too). This is something to anticipate when
purge_all_dead_edges() is called. So although it would be interesting
to find out why the blocks become unreachable so late, I just patched
the compiler at the location where the ICE occurs. The solution is
simply to remove all unreachable basic blocks if
purge_all_dead_edges() nuked some edges.

Bootstrapped&tested on x86_64-unknown-linux-gnu. OK for trunk?

Ciao!
Steven


gcc/
        PR rtl-optimization/46755
        * ira.c (ira): If some dead edges were removed, find and delete
        any blocks that might have become unreachable.

testsuite/
        PR rtl-optimization/46755
        * gfortran.dg/pr46755.f: New test
Steven Bosscher - Dec. 17, 2010, 8:43 p.m.
On Fri, Dec 17, 2010 at 9:38 PM, Steven Bosscher <stevenb.gcc@gmail.com> wrote:
> Hello,
>
> IRA is one of the last passes to recalculate jump labels. With
> Fortran's ASSIGNed GOTO feature, we apparently can end up making
> blocks unreachable this way (and probably a C test case can be
> constructed too).

Ha, I should look at bug comments first. There already *is* a C test case,

void foo (int k)
{
  void *label = k ? &&x : &&y;
  if (k)
    goto *label;
  x: y: ;
}

taken from bug 46465. I will add that bug number to the ChangeLog if
the patch is OK.

Ciao!
Steven
Vladimir Makarov - Dec. 18, 2010, 4:09 p.m.
On 12/17/2010 03:38 PM, Steven Bosscher wrote:
> Hello,
>
> IRA is one of the last passes to recalculate jump labels. With
> Fortran's ASSIGNed GOTO feature, we apparently can end up making
> blocks unreachable this way (and probably a C test case can be
> constructed too). This is something to anticipate when
> purge_all_dead_edges() is called. So although it would be interesting
> to find out why the blocks become unreachable so late, I just patched
> the compiler at the location where the ICE occurs. The solution is
> simply to remove all unreachable basic blocks if
> purge_all_dead_edges() nuked some edges.
>
> Bootstrapped&tested on x86_64-unknown-linux-gnu. OK for trunk?
>
>
Ok.  Thanks for the patch, Steven.

You can add the test (besides already existing one) if you want.  It is 
up to you.

> gcc/
>          PR rtl-optimization/46755
>          * ira.c (ira): If some dead edges were removed, find and delete
>          any blocks that might have become unreachable.
>
> testsuite/
>          PR rtl-optimization/46755
>          * gfortran.dg/pr46755.f: New test
>
> Index: ira.c
> ===================================================================
> --- ira.c       (revision 167996)
> +++ ira.c       (working copy)
> @@ -3158,7 +3158,8 @@ ira (FILE
>          {
>            timevar_push (TV_JUMP);
>            rebuild_jump_labels (get_insns ());
> -         purge_all_dead_edges ();
> +         if (purge_all_dead_edges ())
> +           delete_unreachable_blocks ();
>            timevar_pop (TV_JUMP);
>          }
>       }
> Index: testsuite/gfortran.dg/pr46755.f
> ===================================================================
> --- testsuite/gfortran.dg/pr46755.f	(revision 0)
> +++ testsuite/gfortran.dg/pr46755.f	(revision 0)
> @@ -0,0 +1,23 @@
> +C { dg-do compile }
> +C { dg-options "-O" }
> +      IMPLICIT NONE
> +      INTEGER I640,I760,I800
> +      INTEGER I,ITER,ITMX,LENCM
> +      LOGICAL QDISK,QDW
> +      ASSIGN 801 TO I800
> +      GOTO I800
> + 801  CONTINUE
> +      ASSIGN 761 TO I760
> + 761  CONTINUE
> +      DO I=1,LENCM
> +      ENDDO
> +      DO WHILE(ITER.LT.ITMX)
> +         IF(QDW) THEN
> +            ASSIGN 641 to I640
> +            GOTO I760
> + 641        CONTINUE
> +         ENDIF
> +      ENDDO
> +      RETURN
> +      END
> +

Patch

Index: ira.c
===================================================================
--- ira.c       (revision 167996)
+++ ira.c       (working copy)
@@ -3158,7 +3158,8 @@  ira (FILE
        {
          timevar_push (TV_JUMP);
          rebuild_jump_labels (get_insns ());
-         purge_all_dead_edges ();
+         if (purge_all_dead_edges ())
+           delete_unreachable_blocks ();
          timevar_pop (TV_JUMP);
        }
     }
Index: testsuite/gfortran.dg/pr46755.f
===================================================================
--- testsuite/gfortran.dg/pr46755.f	(revision 0)
+++ testsuite/gfortran.dg/pr46755.f	(revision 0)
@@ -0,0 +1,23 @@ 
+C { dg-do compile }
+C { dg-options "-O" }
+      IMPLICIT NONE
+      INTEGER I640,I760,I800
+      INTEGER I,ITER,ITMX,LENCM
+      LOGICAL QDISK,QDW
+      ASSIGN 801 TO I800
+      GOTO I800
+ 801  CONTINUE
+      ASSIGN 761 TO I760
+ 761  CONTINUE
+      DO I=1,LENCM
+      ENDDO
+      DO WHILE(ITER.LT.ITMX)
+         IF(QDW) THEN
+            ASSIGN 641 to I640
+            GOTO I760
+ 641        CONTINUE
+         ENDIF
+      ENDDO
+      RETURN
+      END
+