Skip to content

Commit 66825de

Browse files
committed
[LAA] Be more careful when evaluating AddRecs at symbolic max BTC.
Evaluating AR at the symbolic max BTC may wrap and create an expression that is less than the start of the AddRec due to wrapping (for example consider MaxBTC = -2). If that's the case, set ScEnd to -(EltSize + 1). ScEnd will get incremented by EltSize before returning, so this effectively sets ScEnd to unsigned max. Note that LAA separately checks that accesses cannot not wrap, so unsigned max represents an upper bound.
1 parent ecd65e6 commit 66825de

File tree

2 files changed

+21
-10
lines changed

2 files changed

+21
-10
lines changed

llvm/lib/Analysis/LoopAccessAnalysis.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,13 +219,29 @@ static std::pair<const SCEV *, const SCEV *> getStartAndEndForAccess(
219219
const SCEV *ScStart;
220220
const SCEV *ScEnd;
221221

222+
auto &DL = Lp->getHeader()->getDataLayout();
223+
Type *IdxTy = DL.getIndexType(PtrExpr->getType());
224+
const SCEV *EltSizeSCEV = SE->getStoreSizeOfExpr(IdxTy, AccessTy);
222225
if (SE->isLoopInvariant(PtrExpr, Lp)) {
223226
ScStart = ScEnd = PtrExpr;
224227
} else if (auto *AR = dyn_cast<SCEVAddRecExpr>(PtrExpr)) {
225-
const SCEV *Ex = PSE.getSymbolicMaxBackedgeTakenCount();
226-
227228
ScStart = AR->getStart();
228-
ScEnd = AR->evaluateAtIteration(Ex, *SE);
229+
const SCEV *BTC = PSE.getBackedgeTakenCount();
230+
if (!isa<SCEVCouldNotCompute>(BTC))
231+
ScEnd = AR->evaluateAtIteration(BTC, *SE);
232+
else {
233+
// Evaluating AR at MaxBTC may wrap and create an expression that is less
234+
// than the start of the AddRec due to wrapping (for example consider
235+
// MaxBTC = -2). If that's the case, set ScEnd to -(EltSize + 1). ScEnd
236+
// will get incremented by EltSize before returning, so this effectively
237+
// sets ScEnd to unsigned max. Note that LAA separately checks that
238+
// accesses cannot not wrap, so unsigned max represents an upper bound.
239+
const SCEV *MaxBTC = PSE.getSymbolicMaxBackedgeTakenCount();
240+
ScEnd = AR->evaluateAtIteration(MaxBTC, *SE);
241+
if (!SE->isKnownNonNegative(SE->getMinusSCEV(ScEnd, ScStart)))
242+
ScEnd = SE->getNegativeSCEV(
243+
SE->getAddExpr(EltSizeSCEV, SE->getOne(EltSizeSCEV->getType())));
244+
}
229245
const SCEV *Step = AR->getStepRecurrence(*SE);
230246

231247
// For expressions with negative step, the upper bound is ScStart and the
@@ -247,9 +263,6 @@ static std::pair<const SCEV *, const SCEV *> getStartAndEndForAccess(
247263
assert(SE->isLoopInvariant(ScEnd, Lp)&& "ScEnd needs to be invariant");
248264

249265
// Add the size of the pointed element to ScEnd.
250-
auto &DL = Lp->getHeader()->getDataLayout();
251-
Type *IdxTy = DL.getIndexType(PtrExpr->getType());
252-
const SCEV *EltSizeSCEV = SE->getStoreSizeOfExpr(IdxTy, AccessTy);
253266
ScEnd = SE->getAddExpr(ScEnd, EltSizeSCEV);
254267

255268
Iter->second = {ScStart, ScEnd};

llvm/test/Analysis/LoopAccessAnalysis/evaluate-at-symbolic-max-backedge-taken-count-may-wrap.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
55

6-
; FIXME: Start == End for access group with AddRec.
76
define void @runtime_checks_with_symbolic_max_btc_neg_1(ptr %P, ptr %S, i32 %x, i32 %y) {
87
; CHECK-LABEL: 'runtime_checks_with_symbolic_max_btc_neg_1'
98
; CHECK-NEXT: loop:
@@ -17,7 +16,7 @@ define void @runtime_checks_with_symbolic_max_btc_neg_1(ptr %P, ptr %S, i32 %x,
1716
; CHECK-NEXT: ptr %S
1817
; CHECK-NEXT: Grouped accesses:
1918
; CHECK-NEXT: Group [[GRP1]]:
20-
; CHECK-NEXT: (Low: ((4 * %y) + %P) High: ((4 * %y) + %P))
19+
; CHECK-NEXT: (Low: ((4 * %y) + %P) High: -1)
2120
; CHECK-NEXT: Member: {((4 * %y) + %P),+,4}<%loop>
2221
; CHECK-NEXT: Group [[GRP2]]:
2322
; CHECK-NEXT: (Low: %S High: (4 + %S))
@@ -44,7 +43,6 @@ exit:
4443
ret void
4544
}
4645

47-
; FIXME: Start > End for access group with AddRec.
4846
define void @runtime_check_with_symbolic_max_btc_neg_2(ptr %P, ptr %S, i32 %x, i32 %y) {
4947
; CHECK-LABEL: 'runtime_check_with_symbolic_max_btc_neg_2'
5048
; CHECK-NEXT: loop:
@@ -58,7 +56,7 @@ define void @runtime_check_with_symbolic_max_btc_neg_2(ptr %P, ptr %S, i32 %x, i
5856
; CHECK-NEXT: ptr %S
5957
; CHECK-NEXT: Grouped accesses:
6058
; CHECK-NEXT: Group [[GRP3]]:
61-
; CHECK-NEXT: (Low: ((4 * %y) + %P) High: (-4 + (4 * %y) + %P))
59+
; CHECK-NEXT: (Low: ((4 * %y) + %P) High: -1)
6260
; CHECK-NEXT: Member: {((4 * %y) + %P),+,4}<%loop>
6361
; CHECK-NEXT: Group [[GRP4]]:
6462
; CHECK-NEXT: (Low: %S High: (4 + %S))

0 commit comments

Comments
 (0)