
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
81 lines
2.6 KiB
LLVM
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
|
|
}
|