Skip to content

Commit c91b942

Browse files
committed
[SCEV] Add predicate in SolveLinEq to ensure B is a multiple of A.
This can help in cases where pointer alignment info is missing, e.g. #108210 The predicate is formed for the complex expression that's passed to SolveLinEquationWithOverflow and the checks could probably be pushed closer to the root nodes, which in some cases may be cheaper to check.
1 parent 6749f2b commit c91b942

File tree

4 files changed

+184
-21
lines changed

4 files changed

+184
-21
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10120,8 +10120,11 @@ const SCEV *ScalarEvolution::stripInjectiveFunctions(const SCEV *S) const {
1012010120
/// A and B isn't important.
1012110121
///
1012210122
/// If the equation does not have a solution, SCEVCouldNotCompute is returned.
10123-
static const SCEV *SolveLinEquationWithOverflow(const APInt &A, const SCEV *B,
10124-
ScalarEvolution &SE) {
10123+
static const SCEV *
10124+
SolveLinEquationWithOverflow(const APInt &A, const SCEV *B,
10125+
SmallPtrSetImpl<const SCEVPredicate *> *Predicates,
10126+
10127+
ScalarEvolution &SE) {
1012510128
uint32_t BW = A.getBitWidth();
1012610129
assert(BW == SE.getTypeSizeInBits(B->getType()));
1012710130
assert(A != 0 && "A must be non-zero.");
@@ -10137,8 +10140,17 @@ static const SCEV *SolveLinEquationWithOverflow(const APInt &A, const SCEV *B,
1013710140
//
1013810141
// B is divisible by D if and only if the multiplicity of prime factor 2 for B
1013910142
// is not less than multiplicity of this prime factor for D.
10140-
if (SE.getMinTrailingZeros(B) < Mult2)
10141-
return SE.getCouldNotCompute();
10143+
if (SE.getMinTrailingZeros(B) < Mult2) {
10144+
if (!Predicates)
10145+
return SE.getCouldNotCompute();
10146+
// Try to add a predicate ensuring B is a multiple of A.
10147+
const SCEV *URem = SE.getURemExpr(B, SE.getConstant(A));
10148+
const SCEV *Zero = SE.getZero(B->getType());
10149+
// Avoid adding a predicate that is known to be false.
10150+
if (SE.isKnownPredicate(CmpInst::ICMP_NE, URem, Zero))
10151+
return SE.getCouldNotCompute();
10152+
Predicates->insert(SE.getEqualPredicate(URem, Zero));
10153+
}
1014210154

1014310155
// 3. Compute I: the multiplicative inverse of (A / D) in arithmetic
1014410156
// modulo (N / D).
@@ -10568,8 +10580,9 @@ ScalarEvolution::ExitLimit ScalarEvolution::howFarToZero(const SCEV *V,
1056810580
// Solve the general equation.
1056910581
if (!StepC || StepC->getValue()->isZero())
1057010582
return getCouldNotCompute();
10571-
const SCEV *E = SolveLinEquationWithOverflow(StepC->getAPInt(),
10572-
getNegativeSCEV(Start), *this);
10583+
const SCEV *E = SolveLinEquationWithOverflow(
10584+
StepC->getAPInt(), getNegativeSCEV(Start),
10585+
AllowPredicates ? &Predicates : nullptr, *this);
1057310586

1057410587
const SCEV *M = E;
1057510588
if (E != getCouldNotCompute()) {

llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,6 +1580,12 @@ define i32 @ptr_induction_ult_2(ptr %a, ptr %b) {
15801580
; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.
15811581
; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
15821582
; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.
1583+
; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (((-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 4)
1584+
; CHECK-NEXT: Predicates:
1585+
; CHECK-NEXT: Equal predicate: (zext i2 ((trunc i64 (ptrtoint ptr %b to i64) to i2) + (-1 * (trunc i64 (ptrtoint ptr %a to i64) to i2))) to i64) == 0
1586+
; CHECK-NEXT: Loop %loop: Predicated symbolic max backedge-taken count is (((-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 4)
1587+
; CHECK-NEXT: Predicates:
1588+
; CHECK-NEXT: Equal predicate: (zext i2 ((trunc i64 (ptrtoint ptr %b to i64) to i2) + (-1 * (trunc i64 (ptrtoint ptr %a to i64) to i2))) to i64) == 0
15831589
;
15841590
entry:
15851591
%cmp.6 = icmp ult ptr %a, %b
@@ -1652,10 +1658,9 @@ exit:
16521658
ret void
16531659
}
16541660

1655-
; TODO: It feels like we should be able to calculate the symbolic max
1656-
; exit count for the loop.inc block here, in the same way as
1657-
; ptr_induction_eq_1. The problem seems to be in howFarToZero when the
1658-
; ControlsOnlyExit is set to false.
1661+
; %a and %b may not have the same alignment, so the loop may only via the early
1662+
; exit when %ptr.iv > %b. The predicated exit count for the latch can be
1663+
; computed by adding a predicate.
16591664
define void @ptr_induction_early_exit_eq_1(ptr %a, ptr %b, ptr %c) {
16601665
; CHECK-LABEL: 'ptr_induction_early_exit_eq_1'
16611666
; CHECK-NEXT: Classifying expressions for: @ptr_induction_early_exit_eq_1
@@ -1669,10 +1674,21 @@ define void @ptr_induction_early_exit_eq_1(ptr %a, ptr %b, ptr %c) {
16691674
; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
16701675
; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
16711676
; CHECK-NEXT: exit count for loop.inc: ***COULDNOTCOMPUTE***
1677+
; CHECK-NEXT: predicated exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
1678+
; CHECK-NEXT: Predicates:
1679+
; CHECK-NEXT: Equal predicate: (zext i3 ((trunc i64 (ptrtoint ptr %b to i64) to i3) + (-1 * (trunc i64 (ptrtoint ptr %a to i64) to i3))) to i64) == 0
1680+
; CHECK-EMPTY:
16721681
; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
16731682
; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.
16741683
; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
16751684
; CHECK-NEXT: symbolic max exit count for loop.inc: ***COULDNOTCOMPUTE***
1685+
; CHECK-NEXT: predicated symbolic max exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
1686+
; CHECK-NEXT: Predicates:
1687+
; CHECK-NEXT: Equal predicate: (zext i3 ((trunc i64 (ptrtoint ptr %b to i64) to i3) + (-1 * (trunc i64 (ptrtoint ptr %a to i64) to i3))) to i64) == 0
1688+
; CHECK-EMPTY:
1689+
; CHECK-NEXT: Loop %loop: Predicated symbolic max backedge-taken count is ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
1690+
; CHECK-NEXT: Predicates:
1691+
; CHECK-NEXT: Equal predicate: (zext i3 ((trunc i64 (ptrtoint ptr %b to i64) to i3) + (-1 * (trunc i64 (ptrtoint ptr %a to i64) to i3))) to i64) == 0
16761692
;
16771693
entry:
16781694
%cmp = icmp eq ptr %a, %b

llvm/test/Analysis/ScalarEvolution/ne-overflow.ll

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ define void @test_well_defined_infinite_st(i32 %N) mustprogress {
5858
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count.
5959
; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count.
6060
; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count.
61+
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is ((-2 + %N) /u 2)
62+
; CHECK-NEXT: Predicates:
63+
; CHECK-NEXT: Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
64+
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is ((-2 + %N) /u 2)
65+
; CHECK-NEXT: Predicates:
66+
; CHECK-NEXT: Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
6167
;
6268
entry:
6369
br label %for.body
@@ -79,6 +85,12 @@ define void @test_well_defined_infinite_ld(i32 %N) mustprogress {
7985
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count.
8086
; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count.
8187
; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count.
88+
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is ((-2 + %N) /u 2)
89+
; CHECK-NEXT: Predicates:
90+
; CHECK-NEXT: Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
91+
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is ((-2 + %N) /u 2)
92+
; CHECK-NEXT: Predicates:
93+
; CHECK-NEXT: Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
8294
;
8395
entry:
8496
br label %for.body
@@ -100,6 +112,12 @@ define void @test_no_mustprogress(i32 %N) {
100112
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count.
101113
; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count.
102114
; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count.
115+
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is ((-2 + %N) /u 2)
116+
; CHECK-NEXT: Predicates:
117+
; CHECK-NEXT: Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
118+
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is ((-2 + %N) /u 2)
119+
; CHECK-NEXT: Predicates:
120+
; CHECK-NEXT: Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
103121
;
104122
entry:
105123
br label %for.body
@@ -187,6 +205,12 @@ define void @test_abnormal_exit(i32 %N) mustprogress {
187205
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count.
188206
; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count.
189207
; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count.
208+
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is ((-2 + %N) /u 2)
209+
; CHECK-NEXT: Predicates:
210+
; CHECK-NEXT: Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
211+
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is ((-2 + %N) /u 2)
212+
; CHECK-NEXT: Predicates:
213+
; CHECK-NEXT: Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
190214
;
191215
entry:
192216
br label %for.body
@@ -209,10 +233,24 @@ define void @test_other_exit(i32 %N) mustprogress {
209233
; CHECK-NEXT: Loop %for.body: <multiple exits> Unpredictable backedge-taken count.
210234
; CHECK-NEXT: exit count for for.body: i32 9
211235
; CHECK-NEXT: exit count for for.latch: ***COULDNOTCOMPUTE***
236+
; CHECK-NEXT: predicated exit count for for.latch: ((-2 + %N) /u 2)
237+
; CHECK-NEXT: Predicates:
238+
; CHECK-NEXT: Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
239+
; CHECK-EMPTY:
212240
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i32 9
213241
; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is i32 9
214242
; CHECK-NEXT: symbolic max exit count for for.body: i32 9
215243
; CHECK-NEXT: symbolic max exit count for for.latch: ***COULDNOTCOMPUTE***
244+
; CHECK-NEXT: predicated symbolic max exit count for for.latch: ((-2 + %N) /u 2)
245+
; CHECK-NEXT: Predicates:
246+
; CHECK-NEXT: Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
247+
; CHECK-EMPTY:
248+
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (9 umin ((-2 + %N) /u 2))
249+
; CHECK-NEXT: Predicates:
250+
; CHECK-NEXT: Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
251+
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is (9 umin ((-2 + %N) /u 2))
252+
; CHECK-NEXT: Predicates:
253+
; CHECK-NEXT: Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
216254
;
217255
entry:
218256
br label %for.body
@@ -264,6 +302,14 @@ define void @test_sext(i64 %N) mustprogress {
264302
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count.
265303
; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count.
266304
; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count.
305+
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (%N /u 2)
306+
; CHECK-NEXT: Predicates:
307+
; CHECK-NEXT: {0,+,2}<%for.body> Added Flags: <nssw>
308+
; CHECK-NEXT: Equal predicate: (zext i1 (trunc i64 %N to i1) to i64) == 0
309+
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is (%N /u 2)
310+
; CHECK-NEXT: Predicates:
311+
; CHECK-NEXT: {0,+,2}<%for.body> Added Flags: <nssw>
312+
; CHECK-NEXT: Equal predicate: (zext i1 (trunc i64 %N to i1) to i64) == 0
267313
;
268314
entry:
269315
br label %for.body
@@ -285,6 +331,16 @@ define void @test_zext_of_sext(i64 %N) mustprogress {
285331
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count.
286332
; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count.
287333
; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count.
334+
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (%N /u 2)
335+
; CHECK-NEXT: Predicates:
336+
; CHECK-NEXT: {0,+,2}<%for.body> Added Flags: <nssw>
337+
; CHECK-NEXT: {0,+,2}<%for.body> Added Flags: <nusw>
338+
; CHECK-NEXT: Equal predicate: (zext i1 (trunc i64 %N to i1) to i64) == 0
339+
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is (%N /u 2)
340+
; CHECK-NEXT: Predicates:
341+
; CHECK-NEXT: {0,+,2}<%for.body> Added Flags: <nssw>
342+
; CHECK-NEXT: {0,+,2}<%for.body> Added Flags: <nusw>
343+
; CHECK-NEXT: Equal predicate: (zext i1 (trunc i64 %N to i1) to i64) == 0
288344
;
289345
entry:
290346
br label %for.body
@@ -307,6 +363,14 @@ define void @test_zext_offset(i64 %N) mustprogress {
307363
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count.
308364
; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count.
309365
; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count.
366+
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is ((-21 + %N) /u 2)
367+
; CHECK-NEXT: Predicates:
368+
; CHECK-NEXT: {0,+,2}<%for.body> Added Flags: <nusw>
369+
; CHECK-NEXT: Equal predicate: (zext i1 (true + (trunc i64 %N to i1)) to i64) == 0
370+
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is ((-21 + %N) /u 2)
371+
; CHECK-NEXT: Predicates:
372+
; CHECK-NEXT: {0,+,2}<%for.body> Added Flags: <nusw>
373+
; CHECK-NEXT: Equal predicate: (zext i1 (true + (trunc i64 %N to i1)) to i64) == 0
310374
;
311375
entry:
312376
br label %for.body
@@ -329,6 +393,14 @@ define void @test_sext_offset(i64 %N) mustprogress {
329393
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count.
330394
; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count.
331395
; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count.
396+
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is ((-21 + %N) /u 2)
397+
; CHECK-NEXT: Predicates:
398+
; CHECK-NEXT: {0,+,2}<%for.body> Added Flags: <nssw>
399+
; CHECK-NEXT: Equal predicate: (zext i1 (true + (trunc i64 %N to i1)) to i64) == 0
400+
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is ((-21 + %N) /u 2)
401+
; CHECK-NEXT: Predicates:
402+
; CHECK-NEXT: {0,+,2}<%for.body> Added Flags: <nssw>
403+
; CHECK-NEXT: Equal predicate: (zext i1 (true + (trunc i64 %N to i1)) to i64) == 0
332404
;
333405
entry:
334406
br label %for.body

0 commit comments

Comments
 (0)