Skip to content

Commit 41f58ca

Browse files
committed
!fixup address comments, thanks
1 parent 2636025 commit 41f58ca

File tree

6 files changed

+126
-91
lines changed

6 files changed

+126
-91
lines changed

llvm/lib/Analysis/LoopAccessAnalysis.cpp

Lines changed: 70 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,31 @@ RuntimeCheckingPtrGroup::RuntimeCheckingPtrGroup(
188188
Members.push_back(Index);
189189
}
190190

191+
/// Returns \p A + \p B, if it is guaranteed not to unsigned wrap. Otherwise
192+
/// return nullptr.
193+
static const SCEV *addSCEVOverflow(const SCEV *A, const SCEV *B,
194+
ScalarEvolution &SE) {
195+
if (!SE.willNotOverflow(Instruction::Add, false, A, B))
196+
return nullptr;
197+
return SE.getAddExpr(A, B);
198+
}
199+
200+
/// Returns \p A * \p B, if it is guaranteed not to unsigned wrap. Otherwise
201+
/// return nullptr.
202+
static const SCEV *mulSCEVOverflow(const SCEV *A, const SCEV *B,
203+
ScalarEvolution &SE) {
204+
if (!SE.willNotOverflow(Instruction::Mul, false, A, B))
205+
return nullptr;
206+
return SE.getMulExpr(A, B);
207+
}
208+
191209
/// Return true, if evaluating \p AR at \p MaxBTC cannot wrap, because \p AR at
192210
/// \p MaxBTC is guaranteed inbounds of the accessed object.
193-
static bool evaluateAddRecAtMaxBTCWillNotWrap(const SCEVAddRecExpr *AR,
194-
const SCEV *MaxBTC,
195-
ScalarEvolution &SE,
196-
const DataLayout &DL) {
211+
static bool evaluatePtrAddRecAtMaxBTCWillNotWrap(const SCEVAddRecExpr *AR,
212+
const SCEV *MaxBTC,
213+
const SCEV *EltSize,
214+
ScalarEvolution &SE,
215+
const DataLayout &DL) {
197216
auto *PointerBase = SE.getPointerBase(AR->getStart());
198217
auto *StartPtr = dyn_cast<SCEVUnknown>(PointerBase);
199218
if (!StartPtr)
@@ -208,29 +227,45 @@ static bool evaluateAddRecAtMaxBTCWillNotWrap(const SCEVAddRecExpr *AR,
208227
const SCEV *Step = AR->getStepRecurrence(SE);
209228
Type *WiderTy = SE.getWiderType(MaxBTC->getType(), Step->getType());
210229
Step = SE.getNoopOrSignExtend(Step, WiderTy);
211-
MaxBTC = SE.getNoopOrSignExtend(MaxBTC, WiderTy);
230+
MaxBTC = SE.getNoopOrZeroExtend(MaxBTC, WiderTy);
231+
232+
// For the computations below, make sure they don't unsigned wrap.
233+
if (!SE.isKnownPredicate(CmpInst::ICMP_UGE, AR->getStart(), StartPtr))
234+
return false;
235+
const SCEV *StartOffset = SE.getNoopOrSignExtend(
236+
SE.getMinusSCEV(AR->getStart(), StartPtr), WiderTy);
237+
238+
const SCEV *OffsetAtLastIter =
239+
mulSCEVOverflow(MaxBTC, SE.getAbsExpr(Step, false), SE);
240+
if (!OffsetAtLastIter)
241+
return false;
242+
243+
const SCEV *OffsetLastAccessedByte = addSCEVOverflow(
244+
OffsetAtLastIter, SE.getNoopOrZeroExtend(EltSize, WiderTy), SE);
245+
if (!OffsetLastAccessedByte)
246+
return false;
247+
212248
if (SE.isKnownPositive(Step)) {
213-
// For positive steps, check if (AR->getStart() - StartPtr) + MaxBTC <=
214-
// DerefBytes / Step
215-
const SCEV *StartOffset = SE.getNoopOrSignExtend(
216-
SE.getMinusSCEV(AR->getStart(), StartPtr), WiderTy);
217-
return SE.isKnownPredicate(
218-
CmpInst::ICMP_ULE, SE.getAddExpr(StartOffset, MaxBTC),
219-
SE.getUDivExpr(SE.getConstant(WiderTy, DerefBytes), Step));
249+
// For positive steps, check if
250+
// (AR->getStart() - StartPtr) + (MaxBTC * Step) + EltSize <= DerefBytes,
251+
// while making sure none of the computations unsigned wrap themselves.
252+
const SCEV *LastAccessedByte =
253+
addSCEVOverflow(StartOffset, OffsetLastAccessedByte, SE);
254+
if (!LastAccessedByte)
255+
return false;
256+
return SE.isKnownPredicate(CmpInst::ICMP_ULE, LastAccessedByte,
257+
SE.getConstant(WiderTy, DerefBytes));
220258
}
259+
221260
if (SE.isKnownNegative(Step)) {
222-
// For negative steps, check using StartOffset == AR->getStart() - StartPtr:
223-
// * StartOffset >= MaxBTC * Step
224-
// * AND StartOffset <= DerefBytes / Step
225-
auto *StartOffset = SE.getNoopOrSignExtend(
226-
SE.getMinusSCEV(AR->getStart(), StartPtr), WiderTy);
227-
return SE.isKnownPredicate(
228-
CmpInst::ICMP_UGE, StartOffset,
229-
SE.getMulExpr(MaxBTC, SE.getNegativeSCEV(Step))) &&
230-
SE.isKnownPredicate(
231-
CmpInst::ICMP_ULE, StartOffset,
232-
SE.getUDivExpr(SE.getConstant(WiderTy, DerefBytes),
233-
SE.getNegativeSCEV(Step)));
261+
// For negative steps check if
262+
// * StartOffset >= (MaxBTC * Step + EltSize)
263+
// * StartOffset <= DerefBytes.
264+
return SE
265+
.isKnownPredicate(CmpInst::ICMP_SGE, StartOffset,
266+
OffsetLastAccessedByte)
267+
SE.isKnownPredicate(CmpInst::ICMP_ULE, StartOffset,
268+
SE.getConstant(WiderTy, DerefBytes));
234269
}
235270
return false;
236271
}
@@ -271,14 +306,18 @@ std::pair<const SCEV *, const SCEV *> llvm::getStartAndEndForAccess(
271306
// than the start of the AddRec due to wrapping (for example consider
272307
// MaxBTC = -2). If that's the case, set ScEnd to -(EltSize + 1). ScEnd
273308
// will get incremented by EltSize before returning, so this effectively
274-
// sets ScEnd to unsigned max. Note that LAA separately checks that
275-
// accesses cannot not wrap, so unsigned max represents an upper bound.
276-
ScEnd = SE->getAddExpr(
277-
SE->getNegativeSCEV(EltSizeSCEV),
278-
SE->getSCEV(ConstantExpr::getIntToPtr(
279-
ConstantInt::get(EltSizeSCEV->getType(), -1), AR->getType())));
280-
if (evaluateAddRecAtMaxBTCWillNotWrap(AR, MaxBTC, *SE, DL))
309+
// sets ScEnd to the maximum unsigned value for the type. Note that LAA
310+
// separately checks that accesses cannot not wrap, so unsigned max
311+
// represents an upper bound.
312+
if (evaluatePtrAddRecAtMaxBTCWillNotWrap(AR, MaxBTC, EltSizeSCEV, *SE,
313+
DL)) {
281314
ScEnd = AR->evaluateAtIteration(MaxBTC, *SE);
315+
} else {
316+
ScEnd = SE->getAddExpr(
317+
SE->getNegativeSCEV(EltSizeSCEV),
318+
SE->getSCEV(ConstantExpr::getIntToPtr(
319+
ConstantInt::get(EltSizeSCEV->getType(), -1), AR->getType())));
320+
}
282321
}
283322
const SCEV *Step = AR->getStepRecurrence(*SE);
284323

llvm/test/Analysis/LoopAccessAnalysis/early-exit-runtime-checks.ll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ define void @all_exits_dominate_latch_countable_exits_at_most_500_iterations_not
7272
; CHECK-NEXT: %gep.A = getelementptr inbounds i32, ptr %A, i64 %iv
7373
; CHECK-NEXT: Grouped accesses:
7474
; CHECK-NEXT: Group GRP0:
75-
; CHECK-NEXT: (Low: %B High: (2000 + %B))
75+
; CHECK-NEXT: (Low: %B High: inttoptr (i64 -1 to ptr))
7676
; CHECK-NEXT: Member: {%B,+,4}<nuw><%loop.header>
7777
; CHECK-NEXT: Group GRP1:
7878
; CHECK-NEXT: (Low: %A High: inttoptr (i64 -1 to ptr))
@@ -130,10 +130,10 @@ define i32 @all_exits_dominate_latch_countable_exits_at_most_1000_iterations_kno
130130
; CHECK-NEXT: %gep.A = getelementptr inbounds i32, ptr %A, i64 %iv
131131
; CHECK-NEXT: Grouped accesses:
132132
; CHECK-NEXT: Group GRP0:
133-
; CHECK-NEXT: (Low: %B High: (4004 + %B))
133+
; CHECK-NEXT: (Low: %B High: inttoptr (i64 -1 to ptr))
134134
; CHECK-NEXT: Member: {%B,+,4}<nuw><%loop.header>
135135
; CHECK-NEXT: Group GRP1:
136-
; CHECK-NEXT: (Low: %A High: (4004 + %A))
136+
; CHECK-NEXT: (Low: %A High: inttoptr (i64 -1 to ptr))
137137
; CHECK-NEXT: Member: {%A,+,4}<nuw><%loop.header>
138138
; CHECK-EMPTY:
139139
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
@@ -188,8 +188,8 @@ define i32 @all_exits_dominate_latch_countable_exits_at_most_1000_iterations_not
188188
; CHECK-NEXT: %gep.A = getelementptr inbounds i32, ptr %A, i64 %iv
189189
; CHECK-NEXT: Grouped accesses:
190190
; CHECK-NEXT: Group GRP0:
191-
; CHECK-NEXT: (Low: %B High: (4004 + %B))
192191
; CHECK-NEXT: (Low: %B High: inttoptr (i64 -1 to ptr))
192+
; CHECK-NEXT: Member: {%B,+,4}<nuw><%loop.header>
193193
; CHECK-NEXT: Group GRP1:
194194
; CHECK-NEXT: (Low: %A High: inttoptr (i64 -1 to ptr))
195195
; CHECK-NEXT: Member: {%A,+,4}<nuw><%loop.header>
@@ -291,10 +291,10 @@ define i32 @b3_does_not_dominate_latch_known_deref(ptr dereferenceable(4000) %A,
291291
; CHECK-NEXT: %gep.A = getelementptr inbounds i32, ptr %A, i64 %iv
292292
; CHECK-NEXT: Grouped accesses:
293293
; CHECK-NEXT: Group GRP0:
294-
; CHECK-NEXT: (Low: %B High: (4004 + %B))
294+
; CHECK-NEXT: (Low: %B High: inttoptr (i64 -1 to ptr))
295295
; CHECK-NEXT: Member: {%B,+,4}<nuw><%loop.header>
296296
; CHECK-NEXT: Group GRP1:
297-
; CHECK-NEXT: (Low: %A High: (4004 + %A))
297+
; CHECK-NEXT: (Low: %A High: inttoptr (i64 -1 to ptr))
298298
; CHECK-NEXT: Member: {%A,+,4}<nuw><%loop.header>
299299
; CHECK-EMPTY:
300300
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.

llvm/test/Analysis/LoopAccessAnalysis/evaluate-at-backedge-taken-count-wrapping.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ define void @pointer_after_object_does_not_wrap(i32 %y, ptr %s, ptr %p) {
1414
; CHECK-NEXT: Dependences:
1515
; CHECK-NEXT: Run-time memory checks:
1616
; CHECK-NEXT: Check 0:
17-
; CHECK-NEXT: Comparing group ([[GRP1:0x[0-9a-f]+]]):
17+
; CHECK-NEXT: Comparing group GRP0:
1818
; CHECK-NEXT: %gep2.iv = getelementptr inbounds i8, ptr %p, i32 %iv
19-
; CHECK-NEXT: Against group ([[GRP2:0x[0-9a-f]+]]):
19+
; CHECK-NEXT: Against group GRP1:
2020
; CHECK-NEXT: %gep1.iv = getelementptr inbounds i8, ptr %s, i32 %iv
2121
; CHECK-NEXT: Grouped accesses:
22-
; CHECK-NEXT: Group [[GRP1]]:
22+
; CHECK-NEXT: Group GRP0:
2323
; CHECK-NEXT: (Low: (%y + %p) High: (2147483647 + %p))
2424
; CHECK-NEXT: Member: {(%y + %p),+,1}<nw><%loop>
25-
; CHECK-NEXT: Group [[GRP2]]:
25+
; CHECK-NEXT: Group GRP1:
2626
; CHECK-NEXT: (Low: (%y + %s) High: (2147483647 + %s))
2727
; CHECK-NEXT: Member: {(%y + %s),+,1}<nw><%loop>
2828
; CHECK-EMPTY:
@@ -57,15 +57,15 @@ define void @pointer_after_object_would_wrap(i32 %y, ptr %s, ptr %p) {
5757
; CHECK-NEXT: Dependences:
5858
; CHECK-NEXT: Run-time memory checks:
5959
; CHECK-NEXT: Check 0:
60-
; CHECK-NEXT: Comparing group ([[GRP3:0x[0-9a-f]+]]):
60+
; CHECK-NEXT: Comparing group GRP0:
6161
; CHECK-NEXT: %gep2.iv = getelementptr inbounds i8, ptr %p, i32 %iv
62-
; CHECK-NEXT: Against group ([[GRP4:0x[0-9a-f]+]]):
62+
; CHECK-NEXT: Against group GRP1:
6363
; CHECK-NEXT: %gep1.iv = getelementptr inbounds i8, ptr %s, i32 %iv
6464
; CHECK-NEXT: Grouped accesses:
65-
; CHECK-NEXT: Group [[GRP3]]:
65+
; CHECK-NEXT: Group GRP0:
6666
; CHECK-NEXT: (Low: (%y + %p) High: (-2147483648 + %p))
6767
; CHECK-NEXT: Member: {(%y + %p),+,1}<nw><%loop>
68-
; CHECK-NEXT: Group [[GRP4]]:
68+
; CHECK-NEXT: Group GRP1:
6969
; CHECK-NEXT: (Low: (%y + %s) High: (-2147483648 + %s))
7070
; CHECK-NEXT: Member: {(%y + %s),+,1}<nw><%loop>
7171
; CHECK-EMPTY:

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

Lines changed: 0 additions & 2 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:
@@ -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:

0 commit comments

Comments
 (0)