Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion llvm/include/llvm/Analysis/LoopCacheAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ class IndexedReference {

/// Attempt to delinearize \p AccessFn for fixed-size arrays.
bool tryDelinearizeFixedSize(const SCEV *AccessFn,
SmallVectorImpl<const SCEV *> &Subscripts);
SmallVectorImpl<const SCEV *> &Subscripts,
const SCEV *ElementSize);

/// Return true if the index reference is invariant with respect to loop \p L.
bool isLoopInvariant(const Loop &L) const;
Expand Down
30 changes: 15 additions & 15 deletions llvm/lib/Analysis/LoopCacheAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,22 +355,22 @@ CacheCostTy IndexedReference::computeRefCost(const Loop &L,
}

bool IndexedReference::tryDelinearizeFixedSize(
const SCEV *AccessFn, SmallVectorImpl<const SCEV *> &Subscripts) {
SmallVector<int, 4> ArraySizes;
if (!tryDelinearizeFixedSizeImpl(&SE, &StoreOrLoadInst, AccessFn, Subscripts,
ArraySizes))
const SCEV *AccessFn, SmallVectorImpl<const SCEV *> &Subscripts,
const SCEV *ElementSize) {
const SCEV *Offset = SE.removePointerBase(AccessFn);
if (!delinearizeFixedSizeArray(SE, Offset, Subscripts, Sizes, ElementSize)) {
Sizes.clear();
return false;
}

// Populate Sizes with scev expressions to be used in calculations later.
for (auto Idx : seq<unsigned>(1, Subscripts.size()))
Sizes.push_back(
SE.getConstant(Subscripts[Idx]->getType(), ArraySizes[Idx - 1]));

LLVM_DEBUG({
dbgs() << "Delinearized subscripts of fixed-size array\n"
<< "GEP:" << *getLoadStorePointerOperand(&StoreOrLoadInst)
<< "\n";
});
// We expect Sizes and Subscipts have the same number of elements, and the
// last element of Sizes is ElementSize. It is for ensuring consistency with
// the load/store instruction being analyzed. It is not needed for further
// analysis.
// TODO: Maybe this property should be enforced in delinearizeFixedSizeArray.
assert(!Sizes.empty() && Subscripts.size() == Sizes.size() &&
Sizes.back() == ElementSize && "Unexpected delinearization result");
Sizes.pop_back();
return true;
}

Expand All @@ -397,7 +397,7 @@ bool IndexedReference::delinearize(const LoopInfo &LI) {

bool IsFixedSize = false;
// Try to delinearize fixed-size arrays.
if (tryDelinearizeFixedSize(AccessFn, Subscripts)) {
if (tryDelinearizeFixedSize(AccessFn, Subscripts, ElemSize)) {
IsFixedSize = true;
// The last element of Sizes is the element size.
Sizes.push_back(ElemSize);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,45 @@
; For a loop with a very large iteration count, make sure the cost
; calculation does not overflow:
;
; void a(int b) {
; for (int c;; c += b)
; void a() {
; for (int c;; c += 2)
; for (long d = 0; d < -3ULL; d += 2ULL)
; A[c][d][d] = 0;
; for (long e = 0; e < -3ULL; e += 2ULL)
; A[c][d][e] = 0;
; }

; CHECK: Loop 'outer.loop' has cost = 9223372036854775807
; CHECK: Loop 'middle.loop' has cost = 9223372036854775807
; CHECK: Loop 'inner.loop' has cost = 9223372036854775807

@A = local_unnamed_addr global [11 x [11 x [11 x i32]]] zeroinitializer, align 16

define void @foo(i32 noundef %b) {
define void @foo() {
entry:
%0 = sext i32 %b to i64
br label %outer.loop

outer.loop:
%indvars.iv = phi i64 [ %indvars.iv.next, %outer.loop.cleanup ], [ 0, %entry ]
br label %inner.loop
br label %middle.loop

outer.loop.cleanup:
%indvars.iv.next = add nsw i64 %indvars.iv, %0
%indvars.iv.next = add i64 %indvars.iv, 2
br label %outer.loop

middle.loop:
%middle.iv = phi i64 [ %middle.iv.next, %middle.loop.cleanup ], [ 0, %outer.loop ]
br label %inner.loop

middle.loop.cleanup:
%middle.iv.next = add nuw i64 %middle.iv, 2
%ec.middle = icmp ult i64 %middle.iv, -5
br i1 %ec.middle, label %middle.loop, label %outer.loop.cleanup

inner.loop:
%inner.iv = phi i64 [ 0, %outer.loop ], [ %add, %inner.loop ]
%arrayidx3 = getelementptr inbounds [11 x [11 x [11 x i32]]], ptr @A, i64 0, i64 %indvars.iv, i64 %inner.iv, i64 %inner.iv
%inner.iv = phi i64 [ 0, %middle.loop ], [ %add, %inner.loop ]
%arrayidx3 = getelementptr inbounds [11 x [11 x [11 x i32]]], ptr @A, i64 0, i64 %indvars.iv, i64 %middle.iv, i64 %inner.iv
store i32 0, ptr %arrayidx3, align 4
%add = add nuw i64 %inner.iv, 2
%cmp = icmp ult i64 %inner.iv, -5
br i1 %cmp, label %inner.loop, label %outer.loop.cleanup
br i1 %cmp, label %inner.loop, label %middle.loop.cleanup
}
2 changes: 1 addition & 1 deletion llvm/test/Transforms/LoopInterchange/pr43326.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t -S \
; RUN: -verify-dom-info -verify-loop-info -verify-loop-lcssa -stats 2>&1
; RUN: -verify-dom-info -verify-loop-info -verify-loop-lcssa -loop-interchange-profitabilities=ignore -stats 2>&1
; RUN: FileCheck --input-file=%t --check-prefix=REMARKS %s

@a = global i32 0
Expand Down
Loading