llvm-project/llvm/test/Analysis/LoopAccessAnalysis/pointer-with-unknown-bounds.ll
Florian Hahn 844c188c79
[LAA] Refine stride checks for SCEVs during dependence analysis. (#99577)
Update getDependenceDistanceStrideAndSize to reason about different
combinations of strides directly and explicitly.

Update getPtrStride to return 0 for invariant pointers.

Then proceed by checking the strides.

If either source or sink are not strided by a constant (i.e. not a
non-wrapping AddRec) or invariant, the accesses may overlap
with earlier or later iterations and we cannot generate runtime
checks to disambiguate them.

Otherwise they are either loop invariant or strided. In that case, we
can generate a runtime check to disambiguate them.

If both are strided by constants, we proceed as previously.

This is an alternative to
https://github.com/llvm/llvm-project/pull/99239 and also replaces
additional checks if the underlying object is loop-invariant.

Fixes https://github.com/llvm/llvm-project/issues/87189.

PR: https://github.com/llvm/llvm-project/pull/99577
2024-07-26 13:10:16 +01:00

81 lines
2.6 KiB
LLVM

; RUN: opt -aa-pipeline=basic-aa -passes='print<access-info>' -disable-output < %s 2>&1 | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
; We shouldn't quit the analysis if we encounter a pointer without known
; bounds *unless* we actually need to emit a memcheck for it. (We only
; compute bounds for SCEVAddRecs so A[i*i] is deemed not having known bounds.)
;
; for (i = 0; i < 20; ++i)
; A[i*i] *= 2;
; CHECK-LABEL: addrec_squared
; CHECK-NEXT: for.body:
; CHECK-NEXT: Report: unsafe dependent memory operations in loop
; CHECK-NOT: Report: cannot identify array bounds
; CHECK-NEXT: Unsafe indirect dependence.
; CHECK-NEXT: Dependences:
; CHECK-NEXT: IndirectUnsafe:
; CHECK-NEXT: %loadA = load i16, ptr %arrayidxA, align 2 ->
; CHECK-NEXT: store i16 %mul, ptr %arrayidxA, align 2
define void @addrec_squared(ptr %a) {
entry:
br label %for.body
for.body: ; preds = %for.body, %entry
%ind = phi i64 [ 0, %entry ], [ %add, %for.body ]
%access_ind = mul i64 %ind, %ind
%arrayidxA = getelementptr inbounds i16, ptr %a, i64 %access_ind
%loadA = load i16, ptr %arrayidxA, align 2
%mul = mul i16 %loadA, 2
store i16 %mul, ptr %arrayidxA, align 2
%add = add nuw nsw i64 %ind, 1
%exitcond = icmp eq i64 %add, 20
br i1 %exitcond, label %for.end, label %for.body
for.end: ; preds = %for.body
ret void
}
; TODO: We cannot compute the bound for %arrayidxA_ub, because the index is
; loaded on each iteration. As %a and %b are no-alias, no memchecks are required
; and unknown bounds should not prevent further analysis.
define void @loaded_bound(ptr noalias %a, ptr noalias %b) {
; CHECK-LABEL: loaded_bound
; CHECK-NEXT: for.body:
; CHECK-NEXT: Report: cannot identify array bounds
; CHECK-NEXT: Dependences:
; CHECK-NEXT: Run-time memory checks:
entry:
br label %for.body
for.body: ; preds = %for.body, %entry
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
%iv.next = add nuw nsw i64 %iv, 1
%arrayidxB = getelementptr inbounds i16, ptr %b, i64 %iv
%loadB = load i16, ptr %arrayidxB, align 2
%arrayidxA_ub = getelementptr inbounds i16, ptr %a, i16 %loadB
%loadA_ub = load i16, ptr %arrayidxA_ub, align 2
%mul = mul i16 %loadB, %loadA_ub
%arrayidxA = getelementptr inbounds i16, ptr %a, i64 %iv
store i16 %mul, ptr %arrayidxA, align 2
%exitcond = icmp eq i64 %iv, 20
br i1 %exitcond, label %for.end, label %for.body
for.end: ; preds = %for.body
ret void
}