[MLIR][Affine] Miscompilation: `--affine-super-vectorize` writes past the iteration space when the trip count is not a multiple of the vector size
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
## Reproducer
### small.mlir
```mlir
memref.global "private" @start : memref<8xi32> = dense<[1, 2, 3, 4, 5, 6, 7, 8]>
func.func private @printMemrefI32(memref<*xi32>)
func.func @main() {
%g = memref.get_global @start : memref<8xi32>
%m = memref.alloc() : memref<8xi32>
memref.copy %g, %m : memref<8xi32> to memref<8xi32>
// Six iterations, over a buffer of eight. Elements 6 and 7 are not touched.
affine.for %j = 0 to 6 {
%v = affine.load %m[%j] : memref<8xi32>
%w = arith.addi %v, %v : i32
affine.store %w, %m[%j] : memref<8xi32>
}
%u = memref.cast %m : memref<8xi32> to memref<*xi32>
call @printMemrefI32(%u) : (memref<*xi32>) -> ()
return
}
```
### To reproduce
**Correct:**
```
mlir-opt small.mlir --lower-affine --convert-vector-to-scf --convert-scf-to-cf \
--convert-vector-to-llvm --expand-strided-metadata --finalize-memref-to-llvm \
--convert-func-to-llvm --convert-ub-to-llvm --convert-arith-to-llvm \
--convert-cf-to-llvm --reconcile-unrealized-casts \
| mlir-runner -e main --entry-point-result=void \
--shared-libs=$LLVM_LIB/libmlir_c_runner_utils.so,$LLVM_LIB/libmlir_runner_utils.so
```
Output:
```
Unranked Memref base@ = 0xaaab023eee00 rank = 1 offset = 0 sizes = [8] strides = [1] data =
[2, 4, 6, 8, 10, 12, 7, 8]
```
**Wrong:**
```
mlir-opt small.mlir --affine-super-vectorize=virtual-vector-size=4 \
--lower-affine --convert-vector-to-scf --convert-scf-to-cf \
--convert-vector-to-llvm --expand-strided-metadata --finalize-memref-to-llvm \
--convert-func-to-llvm --convert-ub-to-llvm --convert-arith-to-llvm \
--convert-cf-to-llvm --reconcile-unrealized-casts \
| mlir-runner -e main --entry-point-result=void \
--shared-libs=$LLVM_LIB/libmlir_c_runner_utils.so,$LLVM_LIB/libmlir_runner_utils.so
```
Output:
```
Unranked Memref base@ = 0xaaaaf738afc0 rank = 1 offset = 0 sizes = [8] strides = [1] data =
[2, 4, 6, 8, 10, 12, 14, 16]
```
The loop doubles elements 0 through 5. Elements 6 and 7 keep their input values `7` and `8` without the pass, and are doubled to `14` and `16` with it.
Contributor guide
Research direction
Start by running the provided small.mlir reproducer with and without --affine-super-vectorize=virtual-vector-size=4, then compare the printed buffers. The fix is complete when the transformed loop preserves elements 6 and 7 for the six-iteration trip count, and the reproducer reports [2, 4, 6, 8, 10, 12, 7, 8].
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100