[llvm] [LAA] Be more precise on different store sizes (PR #122318)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 21 09:48:10 PDT 2025


fhahn wrote:

> I think I found a problematic case:
> 
> ```
> define void @one(ptr %dst) {
> entry:
>   %gep.10 = getelementptr nuw i8, ptr %dst, i64 10
>   br label %loop
> 
> loop:
>   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
>   %gep.iv = getelementptr i8, ptr %dst, i64 %iv
>   store i32 0, ptr %gep.iv, align 2
>   %gep.10.iv = getelementptr i8, ptr %gep.10, i64 %iv
>   store i32 1, ptr %gep.10.iv, align 1
>   %iv.next = add i64 %iv, 8
>   %ec = icmp eq i64 %iv.next, 64
>   br i1 %ec, label %exit, label %loop
> 
> exit:                            ; preds = %loop
>   ret void
> }
> ```
> 
> Here both stores have the same size and this formula is correct and give 12:
> 
> ```
> uint64_t MinDistanceNeeded = MaxStride * (MinNumIter - 1) + TypeByteSize;
> ```
> 
> We have these accesses each iteration with VF == 2:
> 
> ```
> ; dst[i+0..3,8..11] - first store
> ; dst[i+10..13,18..21] - second store
> ```
> 
> And LAA correctly determines that they overlap:
> 
> ```
> LAA: Failure because of positive minimum distance 10 but MinDistanceNeeded is 12
> ```
> 
> if we use both store type of `i16`, the code is vectorisable with VF=2:
> 
> ```
> LAA: No unsafe dependent memory operations in loop.  We don't need runtime memory checks.
> ```
> 
> However, if we take first store size as i32 (or i64) and second is i16, there should be a conflict, because ranges overlap:
> 
> ```
> define void @two(ptr %dst) {
> entry:
>   %gep.10 = getelementptr nuw i8, ptr %dst, i64 10
>   br label %loop
> 
> loop:
>   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
>   %gep.iv = getelementptr i8, ptr %dst, i64 %iv
>   store i32 0, ptr %gep.iv, align 2
>   %gep.10.iv = getelementptr i8, ptr %gep.10, i64 %iv
>   store i16 1, ptr %gep.10.iv, align 1
>   %iv.next = add i64 %iv, 8
>   %ec = icmp eq i64 %iv.next, 64
>   br i1 %ec, label %exit, label %loop
> 
> exit:                            ; preds = %loop
>   ret void
> }
> ```
> 
> Accessed elements:
> 
> ```
> ; dst[i+0..3,8..11]
> ; dst[i+10..11,18..19]
> ```
> 
> However we get this output:
> 
> ```
> LAA: No unsafe dependent memory operations in loop.  We don't need runtime memory checks.
> ```

Yeah, this is probably related to https://github.com/llvm/llvm-project/pull/122318#discussion_r2219387590, as `TypeByteSize` will be zero in case they don't match. We definitely need to use a size. I've not checked, but probably using the max size should be a good upper bound

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


More information about the llvm-commits mailing list