[PATCH] D105216: [ScalarEvolution] Fix overflow in computeBECount.

Eli Friedman via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 7 15:15:29 PDT 2021


efriedma added inline comments.


================
Comment at: llvm/lib/Analysis/ScalarEvolution.cpp:11455
+      if (StrideC->getAPInt().isPowerOf2()) {
+        // If the stride is a power of two, the maximum backedge-taken count is
+        // is (2^bitwidth / Stride) - 1.  After that, the addrec repeats values.
----------------
reames wrote:
> I'm not sure this holds, let me walk you through why.  
> 
> There is no guarantee that this exit must be taken.  Instead, some other exit could be taken.
> 
> The cornercase here is when we have an exit (which won't be taken) whose no-wrap IV does in fact wrap on the last iteration (producing poison), but whose value we don't branch on (e.g. no UB) because an earlier exit is taken instead. 
> 
> I believe this means the minimum BTC we can report for the (untaken) exit is 2^BW/Stride.  (e.g. so it must be >= the exit count of the taken exit)
> 
> I believe that invalidates your inequality, and thus your result.
> 
> We can patch this in a couple of ways:
> - If ControlsExit is true, then we know this condition is branched on by the sole exit.  Thus, no other exit, and logic holds.
> - If we know this condition is branched on by any latch dominating exit, then we know that the execution of iteration 2^BW/Stride must execute UB if no earlier exit is taken.  Thus, either this exit is taken on a previous iteration, or another exit is taken up to that iteration.  (I got stuck here, but it really seems like we should be able to do case analysis?)
> 
> Aside: If we already know the other exit count is small, it's a real shame we can't use that here...  Maybe we can do a two step analysis and simplify using min approach?  Just a thought.  
If ControlsExit is false, and stride isn't one, it's hard to get here. I think the only way is if canIVOverflowOnLT returns false, which I think is enough to prevent any trouble here?  Maybe worth going into in the comment, though.


================
Comment at: llvm/lib/Analysis/ScalarEvolution.cpp:11508
+        // FIXME: Signed equivalent?
+        if (!IsSigned && EndC->getAPInt().ule(-StrideC->getAPInt()))
+          return false;
----------------
reames wrote:
> This appears to hold, though I didn't follow the logic TBH.  I resorted to writing a small program to brute force the i8 space.  :)
> 
> Please state the !IsSigned precondition in the comment in End >=u Start form.  
> 
> 
It's basically just proving "end + (stride-1)" doesn't overflow.  I'll try to clarify the comment.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D105216/new/

https://reviews.llvm.org/D105216



More information about the llvm-commits mailing list