[PATCH] [LAA] Try to prove non-wrapping of pointers if SCEV cannot

Adam Nemet anemet at apple.com
Tue Jun 16 15:30:34 PDT 2015

Comment at: lib/Analysis/LoopAccessAnalysis.cpp:509
@@ +508,3 @@
+/// i.e. monotonically increasing/decreasing.
+static bool isNoWrapAddRec(Value *Ptr, const SCEVAddRecExpr *AR,
+                           ScalarEvolution *SE, const Loop *L) {
sanjoy wrote:
> I'm not clear on how LAA uses this property, but I think this function should mention what kind of no-wrap (signed or unsigned) behavior it is trying to prove.  IOW, Ptr is supposed to be  monotonically increasing/decreasing in the signed or unsigned sense?
It's unsigned.  Pointers are unsigned in LLVM IR as mentioned in the GEP FAQ.  I'll add a comment.

Comment at: lib/Analysis/LoopAccessAnalysis.cpp:540
@@ +539,3 @@
+  // using a non-wrapping operation.
+  if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(NonConstIndex))
+    if ((OBO->hasNoUnsignedWrap() || OBO->hasNoSignedWrap()) &&
sanjoy wrote:
> What if `OBO` is `nuw` (and not `nsw`) and `OpAR` is `nsw` (and not `nuw`)?  Or vice-versa?
Yeah, this certainly required more thinking on my behalf, thanks for pressing it.

So to document why this was wrong, let's take this counterexample:

Consider the AddRec {0,+,100} <nuw> in i8.  The first three iterations of that yields: 0, 100, 200.

Putting this through a *signed* add of 3, the input is now interpreted as signed: 0, 100, -56.

No signed overflow on the result (3, 103, -53), yet the result is wrapped. 

Similarly, we can't take <nuw>-only for index.  Index is interpreted as signed.  With the above (i8) {0,+,100} example we'd get a wrapping range even though it may be inbounds for the array. 

Let me know if you or others disagree or have further comments.  Otherwise I'll update the patch accordingly.



More information about the llvm-commits mailing list