On Mon, May 20, 2019 at 4:51 PM Feng Xue OS <f...@os.amperecomputing.com> wrote: > > > I don't see how it is safe in a late pass when it is not safe in an > > > earlier one. Optimization is imperfect - we could fail to remove > > an "obvious" never taken exit and still have a loop that appears to be > > finite according to our definition. > > Yes. it is. This is somewhat similar to strict-alias option/loop dep pragma. > Compiler tries to do something based on hint you tell it, but does not ensure > correctness. > > > The only way > > to define it would be if there was, at any point, an exit from the > > loop (and there it _may_ be exclude EH edges) then > > the loop is assumed to be finite. > > No catch your point. If we treat an infinite loop as finite, it's bad because > the loop might be removed. > > Suppose we have a function: > > void foo(int bound) > { for (int i = 0; i <= bound; i++); } > > In an early CD-DCE pass, "bound" is represented as a variable, and loop has > a exit, so it is assumed to finite, and is removed. > > But in a late pass, this function is inlined into another one, and "bound" > has value of INT_MAX, this loop is infinite, and here we can know it should > not be removed.
But if "bound" is always INT_MAX but that's not visible to the compiler we will still remove the loop so I see no difference with removing it always. > This is why I suggest doing the optimization as late as possible. But this will defeat the purpose of allowing followup optimizations. IMHO the only "sensible" thing is to do Index: gcc/tree-ssa-dce.c =================================================================== --- gcc/tree-ssa-dce.c (revision 271415) +++ gcc/tree-ssa-dce.c (working copy) @@ -417,7 +417,7 @@ find_obviously_necessary_stmts (bool agg } FOR_EACH_LOOP (loop, 0) - if (!finite_loop_p (loop)) + if (!loop_has_exit_edges (loop)) { if (dump_file) fprintf (dump_file, "cannot prove finiteness of loop %i\n", loop->num); that also has the obvious advantage that we don't need to replace the loop with a trap() but have a place to forward control flow to. The loop in the following testcase is then successfully removed: int main(int argc, char **argv) { unsigned i = argc; while (i+=2); return 0; } Likewise is the loop void **q; int main(int argc, char **argv) { void **p = q; while (p = (void **)*p); return 0; } (that's the pointer-chasing). Not with -fnon-call-exceptions -fexceptions though. Richard. > Feng >