On Wed, 11 May 2016, Richard Biener wrote:

> On Tue, 10 May 2016, Richard Biener wrote:
> 
> > 
> > ifcvt is confused about fake edges not being loop exits which the 
> > following fixes.
> > 
> > Bootstrap / regtest pending on x86_64-unknown-linux-gnu.
> 
> Didn't fare well.  The following patch mitigates the issue as well
> but in the end make it just latent - it is still sth I wanted
> to persue anyway seeing the sometimes odd choices for added
> fake edges.  The patch reduces the number from two to one
> and adds it to the real dead-end infinite loop only for the
> testcases.
> 
> 2016-05-11  Richard Biener  <rguent...@suse.de>
> 
>       PR tree-optimization/70986
>       * cfganal.c (dfs_find_deadend): Prefer to take edges exiting
>       loops.
> 
>       * gcc.dg/torture/pr70986-1.c: New testcase.
>       * gcc.dg/torture/pr70986-2.c: Likewise.
>       * gcc.dg/torture/pr70986-3.c: Likewise.
> 
> Index: gcc/testsuite/gcc.dg/torture/pr70986-1.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/pr70986-1.c  (revision 0)
> +++ gcc/testsuite/gcc.dg/torture/pr70986-1.c  (working copy)
> @@ -0,0 +1,22 @@
> +/* { dg-do compile } */
> +
> +int a, g;
> +char b, c;
> +short d, e, f;
> +
> +char
> +fn1 ()
> +{
> +  return a ? a : 1;
> +}
> +
> +void
> +fn2 ()
> +{
> +  char h;
> +  for (; d;)
> +    for (; e; e++)
> +      c = (fn1 () && h) & !(f |= 9 ^ (b > (g = c)));
> +  for (;;)
> +    ;
> +}
> Index: gcc/testsuite/gcc.dg/torture/pr70986-2.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/pr70986-2.c  (revision 0)
> +++ gcc/testsuite/gcc.dg/torture/pr70986-2.c  (working copy)
> @@ -0,0 +1,20 @@
> +/* { dg-do compile } */
> +
> +int gi, dg;
> +
> +void
> +fe (void)
> +{
> +  int ka = gi;
> +
> +  for (;;)
> +    {
> +      if (ka != 0)
> +     {
> +       if (dg != 0)
> +         gi = 0;
> +       ++ka;
> +     }
> +      ++dg;
> +    }
> +}
> Index: gcc/testsuite/gcc.dg/torture/pr70986-3.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/pr70986-3.c  (revision 0)
> +++ gcc/testsuite/gcc.dg/torture/pr70986-3.c  (working copy)
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +
> +int a, b;
> +int
> +fn1 (int p1)
> +{
> +  return p1 < 0 ? p1 : a;
> +}
> +
> +void
> +fn2 ()
> +{
> +lbl_100:
> +  b = 1;
> +  for (; b != 21; b = fn1 (b))
> +    ;
> +  goto lbl_100;
> +}
> Index: gcc/cfganal.c
> ===================================================================
> *** gcc/cfganal.c     (revision 236069)
> --- gcc/cfganal.c     (working copy)
> *************** dfs_find_deadend (basic_block bb)
> *** 747,753 ****
>             return bb;
>           }
>   
> !       bb = EDGE_SUCC (bb, 0)->dest;
>       }
>   
>     gcc_unreachable ();
> --- 751,771 ----
>             return bb;
>           }
>   
> !       /* If we are in an analyzed cycle make sure to try exiting it.
> !          Note this is a heuristic only and expected to work when loop
> !      fixup is needed as well.  */
> !       if (! bb->loop_father
> !       || ! loop_outer (bb->loop_father))
> !     bb = EDGE_SUCC (bb, 0)->dest;
> !       else
> !     {
> !       edge_iterator ei;
> !       edge e;
> !       FOR_EACH_EDGE (e, ei, bb->succs)
> !         if (bb->loop_father != e->dest->loop_father)

Actually I'll test using loop_exit_edge_p (bb->loop_father, e) as the
above may choose to enter a subloop.

Richard.

Reply via email to