aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Analysis/LoopCacheAnalysis.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-24 15:11:41 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-08 19:04:38 +0000
commitfcaf7f8644a9988098ac6be2165bce3ea4786e91 (patch)
tree08a554363df16b968a623d651c09d82a5a0b1c65 /contrib/llvm-project/llvm/lib/Analysis/LoopCacheAnalysis.cpp
parent753f127f3ace09432b2baeffd71a308760641a62 (diff)
parent4b4fe385e49bd883fd183b5f21c1ea486c722e61 (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Analysis/LoopCacheAnalysis.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Analysis/LoopCacheAnalysis.cpp29
1 files changed, 19 insertions, 10 deletions
diff --git a/contrib/llvm-project/llvm/lib/Analysis/LoopCacheAnalysis.cpp b/contrib/llvm-project/llvm/lib/Analysis/LoopCacheAnalysis.cpp
index 2cbf1f7f2d28..85f2dad86711 100644
--- a/contrib/llvm-project/llvm/lib/Analysis/LoopCacheAnalysis.cpp
+++ b/contrib/llvm-project/llvm/lib/Analysis/LoopCacheAnalysis.cpp
@@ -289,18 +289,14 @@ CacheCostTy IndexedReference::computeRefCost(const Loop &L,
LLVM_DEBUG(dbgs() << "TripCount=" << *TripCount << "\n");
const SCEV *RefCost = nullptr;
- if (isConsecutive(L, CLS)) {
+ const SCEV *Stride = nullptr;
+ if (isConsecutive(L, Stride, CLS)) {
// If the indexed reference is 'consecutive' the cost is
// (TripCount*Stride)/CLS.
- const SCEV *Coeff = getLastCoefficient();
- const SCEV *ElemSize = Sizes.back();
- assert(Coeff->getType() == ElemSize->getType() &&
- "Expecting the same type");
- const SCEV *Stride = SE.getMulExpr(Coeff, ElemSize);
+ assert(Stride != nullptr &&
+ "Stride should not be null for consecutive access!");
Type *WiderType = SE.getWiderType(Stride->getType(), TripCount->getType());
const SCEV *CacheLineSize = SE.getConstant(WiderType, CLS);
- if (SE.isKnownNegative(Stride))
- Stride = SE.getNegativeSCEV(Stride);
Stride = SE.getNoopOrAnyExtend(Stride, WiderType);
TripCount = SE.getNoopOrAnyExtend(TripCount, WiderType);
const SCEV *Numerator = SE.getMulExpr(Stride, TripCount);
@@ -464,7 +460,8 @@ bool IndexedReference::isLoopInvariant(const Loop &L) const {
return allCoeffForLoopAreZero;
}
-bool IndexedReference::isConsecutive(const Loop &L, unsigned CLS) const {
+bool IndexedReference::isConsecutive(const Loop &L, const SCEV *&Stride,
+ unsigned CLS) const {
// The indexed reference is 'consecutive' if the only coefficient that uses
// the loop induction variable is the last one...
const SCEV *LastSubscript = Subscripts.back();
@@ -478,7 +475,19 @@ bool IndexedReference::isConsecutive(const Loop &L, unsigned CLS) const {
// ...and the access stride is less than the cache line size.
const SCEV *Coeff = getLastCoefficient();
const SCEV *ElemSize = Sizes.back();
- const SCEV *Stride = SE.getMulExpr(Coeff, ElemSize);
+ Type *WiderType = SE.getWiderType(Coeff->getType(), ElemSize->getType());
+ // FIXME: This assumes that all values are signed integers which may
+ // be incorrect in unusual codes and incorrectly use sext instead of zext.
+ // for (uint32_t i = 0; i < 512; ++i) {
+ // uint8_t trunc = i;
+ // A[trunc] = 42;
+ // }
+ // This consecutively iterates twice over A. If `trunc` is sign-extended,
+ // we would conclude that this may iterate backwards over the array.
+ // However, LoopCacheAnalysis is heuristic anyway and transformations must
+ // not result in wrong optimizations if the heuristic was incorrect.
+ Stride = SE.getMulExpr(SE.getNoopOrSignExtend(Coeff, WiderType),
+ SE.getNoopOrSignExtend(ElemSize, WiderType));
const SCEV *CacheLineSize = SE.getConstant(Stride->getType(), CLS);
Stride = SE.isKnownNegative(Stride) ? SE.getNegativeSCEV(Stride) : Stride;