[Mlir-commits] [mlir] [mlir][VectorToLLVM] emit `inbounds|nuw` GEP flags when lowering `vector.load/store` (PR #202118)

Krzysztof Drewniak llvmlistbot at llvm.org
Sat Jun 13 13:34:37 PDT 2026


krzysz00 wrote:

1. I could've sworn we didn't allow negative strides in memref, so `nuw` and `inbounds` on `memref.load` is correct
2. I still think that putting flags on `vector.load` for "this has 0 <= idx < dim for all dimensions" and "none of these indices are negative" as extra assumptions you can encode is the right move - it means that if you don't set these flags, we just don't say `inbounds` and `nuw`
3. Last I checked, LLVM *doesn't* produce poison if you index outside of an object with a non-`inbounds` GEP, hence the flag? Like, I'm pretty sure you're allowed to do
```llvm
;; %x points to a [2 x i32]
;; %y is a valid pointer to the end of %x, as in .end() for array iterators in C++
%y = getelementptr i32, ptr %x, i64 3
;; this is probably UB, or at least target-defined
%l = load i32, ptr %y
```

So you only get immediate `poison` if you mark the GEP `inbounds`.

(Now, for buffer fat pointers, everything works out. If you `inbounds` your pointer, you're promising you're in the logical object pointer pointed to by the resource. If you don't, you're off the edge of the object, and target-specific documentation says that going off the end means reading 0 / dropping writes (maybe not super-clearly but), which is a perfectly correct refinement of LLVM UB.

Also, the OOB tail is LLVM-level UB, but, again, in graphics contexts or other such cases, you can absolutely have *defined* behavior for such a tail. It's perhaps more correct to say that OOB tails, OOB start indices, etc. have *implementation-defined* behavior at the MLIR level. If you want to explicitly exclude the possibility, you should put a flag on.

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


More information about the Mlir-commits mailing list