[llvm] [LoopVectorize] Add support for reverse loops in isDereferenceableAndAlignedInLoop (PR #96752)

David Sherwood via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 12 01:56:41 PDT 2024


================
@@ -318,11 +321,24 @@ bool llvm::isDereferenceableAndAlignedInLoop(LoadInst *LI, Loop *L,
       // TODO: generalize if a case found which warrants
       if (Offset->getAPInt().urem(Alignment.value()) != 0)
         return false;
+      if (StepIsNegative) {
+        // In the last iteration of the loop the address we access we will be
+        // lower than the first by (TC - 1) * Step. So we need to make sure
+        // that there is enough room in Offset to accomodate this.
+        APInt SubOffset = (TC - 1) * AbsStep;
+        if (Offset->getAPInt().ult(SubOffset))
+          return false;
+        // We can safely use the new base because the decrementing pointer is
+        // always guaranteed to be >= new base. The total access size needs to
+        // take into account the start offset and the loaded element size.
+        AccessSize = Offset->getAPInt() + EltSize;
----------------
david-arm wrote:

Right, so the offset is coming out as 64-bits, but it's probably not what you were expecting - Offset = 0xFFFFFFFFFFFFFFFF. Again, I think it's because the offset in a GEP is treated as being signed so (i8 255) is equivalent to (i8 -1) and is being sign-extended to (i64 -1). So yes technically when we try to (unsigned) add the element size (1 byte) to the offset it overflows, but I'm not sure we can rely upon that for testing overflow behaviour.

This actually makes me wonder whether there are already problems with the existing code, which seems to unconditionally treat the offset as unsigned. For example, should this code

```
       // TODO: generalize if a case found which warrants
       if (Offset->getAPInt().urem(Alignment.value()) != 0)
         return false;
```

be rewritten to

```
       // TODO: generalize if a case found which warrants
       if (Offset->getAPInt().srem(Alignment.value()) != 0)
         return false;
```

etc?

https://github.com/llvm/llvm-project/pull/96752


More information about the llvm-commits mailing list