This is an archive of the discontinued LLVM Phabricator instance.

[SCEV][NFC] Introduce utility functions that measure number of iterations before overflow
AbandonedPublic

Authored by mkazantsev on Feb 21 2018, 10:47 PM.

Details

Summary

Current implementation of getBackedgeTakenCount returns the number of iterations if the loop
exits by its latch condition and not by some side exit (like exception throw or guard). On the other
hand, nsw/nuw flags in AddRecExpr guarantee no-overflow in real loop execution. In patricular,
it can be set based on fact that we have proved that the loop always exits by guard after some iterations.

This inconsistence lures to make an assumption that if an AddRec has no-wrap flag then it will not overflow
if we make getBackedgeTakenCount iterations, and it is incorrect. It creates dangerous pitfalls, see details
of https://reviews.llvm.org/D37569 as an example. In particular, we cannot use the fact that some monotonic
predicate is true on first and last iteration to prove that it is also true on every intermediate iteration just because
the monotonicity could be proved from guard and last iteration is calculated with getBackedgeTakenCount.

To resolve this contradiction and keeping feasibility to use monotonicity to prove facts, we need to be able to prove
that an AddRecExpr does not overflow even if the looop getBackedgeTakenCount iterations (EVEN if it is impossible
and we always exit by guard before it happens). You can think of it as "let us disable all side exit, actually make this
number of iterations and see if it is overflown".

This patch introduces a function that can be used to make this check.

Diff Detail

Event Timeline

sanjoy added inline comments.Feb 21 2018, 11:38 PM
lib/Analysis/ScalarEvolution.cpp
6446

I'm not sure this is sound -- the backedge taken count you compute here can itself be dependent on the nuw/nsw flags, i.e. something like (this exact example may not work):

i = 300;
do {
  guard(i u< 900);
} while (++i u< 200);

In theory the add rec for i can be proved nuw based on the guard and that can be used to upper bound the ++i u< 200 trip count to ~0u - 300 since other i would have to unsigned overflow.

mkazantsev added inline comments.Feb 25 2018, 8:43 PM
lib/Analysis/ScalarEvolution.cpp
6446

I gave it some thought on the weekends, and the possibility of such situation also bugs me. Let me think of the alternative solution that doesn't use monotonicity to prove the fact that we have here.

mkazantsev abandoned this revision.Feb 26 2018, 3:06 AM

Not sure is it a bug or not, but I've found a better way to solve the problem. Abandoning in favor of patch https://reviews.llvm.org/D43759