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.