Adds new optimization remarks when vectorization fails. More specifically, new remarks are added for following 4 cases: - Backward dependency - Backward dependency that prevents Store-to-load forwarding - Forward dependency that prevents Store-to-load forwarding - Unknown dependency It is important to note that only one of the sources of failures (to vectorize) is reported by the remarks. This source of failure may not be first in program order. A regression test has been added to test the following cases: a) Loop can be vectorized: No optimization remark is emitted b) Loop can not be vectorized: In this case an optimization remark will be emitted for one source of failure. Reviewed By: sdesmalen, david-arm Differential Revision: https://reviews.llvm.org/D108371
81 lines
2.6 KiB
LLVM
81 lines
2.6 KiB
LLVM
; RUN: opt -aa-pipeline=basic-aa -passes='require<scalar-evolution>,require<aa>,loop(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: Unknown data dependence.
|
|
; CHECK-NEXT: Dependences:
|
|
; CHECK-NEXT: Unknown:
|
|
; CHECK-NEXT: %loadA = load i16, i16* %arrayidxA, align 2 ->
|
|
; CHECK-NEXT: store i16 %mul, i16* %arrayidxA, align 2
|
|
|
|
define void @addrec_squared(i16* %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, i16* %a, i64 %access_ind
|
|
%loadA = load i16, i16* %arrayidxA, align 2
|
|
|
|
%mul = mul i16 %loadA, 2
|
|
|
|
store i16 %mul, i16* %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(i16* noalias %a, i16* 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, i16* %b, i64 %iv
|
|
%loadB = load i16, i16* %arrayidxB, align 2
|
|
|
|
%arrayidxA_ub = getelementptr inbounds i16, i16* %a, i16 %loadB
|
|
%loadA_ub = load i16, i16* %arrayidxA_ub, align 2
|
|
|
|
%mul = mul i16 %loadB, %loadA_ub
|
|
|
|
%arrayidxA = getelementptr inbounds i16, i16* %a, i64 %iv
|
|
store i16 %mul, i16* %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
|
|
}
|