Skip to content

Commit 6022a8b

Browse files
committed
[SCEV] Drop cached ranges of AddRecs after flag update
Our range computation methods benefit from no-wrap flags. But if the ranges were first computed before the flags were set, the cached range will be too pessimistic. We need to drop cached ranges whenever we sharpen AddRec's no wrap flags. Differential Revision: https://reviews.llvm.org/D89847 Reviewed By: fhahn
1 parent d93287c commit 6022a8b

File tree

4 files changed

+31
-17
lines changed

4 files changed

+31
-17
lines changed

llvm/include/llvm/Analysis/ScalarEvolution.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,11 @@ class ScalarEvolution {
11571157
/// to be a constant.
11581158
Optional<APInt> computeConstantDifference(const SCEV *LHS, const SCEV *RHS);
11591159

1160+
/// Update no-wrap flags of an AddRec. This may drop the cached info about
1161+
/// this AddRec (such as range info) in case if new flags may potentially
1162+
/// sharpen it.
1163+
void setNoWrapFlags(SCEVAddRecExpr *AddRec, SCEV::NoWrapFlags Flags);
1164+
11601165
private:
11611166
/// A CallbackVH to arrange for ScalarEvolution to be notified whenever a
11621167
/// Value is deleted.

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,7 +1381,7 @@ static const SCEV *getPreStartForExtend(const SCEVAddRecExpr *AR, Type *Ty,
13811381
// If we know `AR` == {`PreStart`+`Step`,+,`Step`} is `WrapType` (FlagNSW
13821382
// or FlagNUW) and that `PreStart` + `Step` is `WrapType` too, then
13831383
// `PreAR` == {`PreStart`,+,`Step`} is also `WrapType`. Cache this fact.
1384-
const_cast<SCEVAddRecExpr *>(PreAR)->setNoWrapFlags(WrapType);
1384+
SE->setNoWrapFlags(const_cast<SCEVAddRecExpr *>(PreAR), WrapType);
13851385
}
13861386
return PreStart;
13871387
}
@@ -1585,7 +1585,7 @@ ScalarEvolution::getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
15851585

15861586
if (!AR->hasNoUnsignedWrap()) {
15871587
auto NewFlags = proveNoWrapViaConstantRanges(AR);
1588-
const_cast<SCEVAddRecExpr *>(AR)->setNoWrapFlags(NewFlags);
1588+
setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), NewFlags);
15891589
}
15901590

15911591
// If we have special knowledge that this addrec won't overflow,
@@ -1634,7 +1634,7 @@ ScalarEvolution::getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
16341634
SCEV::FlagAnyWrap, Depth + 1);
16351635
if (ZAdd == OperandExtendedAdd) {
16361636
// Cache knowledge of AR NUW, which is propagated to this AddRec.
1637-
const_cast<SCEVAddRecExpr *>(AR)->setNoWrapFlags(SCEV::FlagNUW);
1637+
setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNUW);
16381638
// Return the expression with the addrec on the outside.
16391639
return getAddRecExpr(
16401640
getExtendAddRecStart<SCEVZeroExtendExpr>(AR, Ty, this,
@@ -1653,7 +1653,7 @@ ScalarEvolution::getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
16531653
if (ZAdd == OperandExtendedAdd) {
16541654
// Cache knowledge of AR NW, which is propagated to this AddRec.
16551655
// Negative step causes unsigned wrap, but it still can't self-wrap.
1656-
const_cast<SCEVAddRecExpr *>(AR)->setNoWrapFlags(SCEV::FlagNW);
1656+
setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNW);
16571657
// Return the expression with the addrec on the outside.
16581658
return getAddRecExpr(
16591659
getExtendAddRecStart<SCEVZeroExtendExpr>(AR, Ty, this,
@@ -1685,7 +1685,7 @@ ScalarEvolution::getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
16851685
isKnownOnEveryIteration(ICmpInst::ICMP_ULT, AR, N)) {
16861686
// Cache knowledge of AR NUW, which is propagated to this
16871687
// AddRec.
1688-
const_cast<SCEVAddRecExpr *>(AR)->setNoWrapFlags(SCEV::FlagNUW);
1688+
setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNUW);
16891689
// Return the expression with the addrec on the outside.
16901690
return getAddRecExpr(
16911691
getExtendAddRecStart<SCEVZeroExtendExpr>(AR, Ty, this,
@@ -1701,7 +1701,7 @@ ScalarEvolution::getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
17011701
// Cache knowledge of AR NW, which is propagated to this
17021702
// AddRec. Negative step causes unsigned wrap, but it
17031703
// still can't self-wrap.
1704-
const_cast<SCEVAddRecExpr *>(AR)->setNoWrapFlags(SCEV::FlagNW);
1704+
setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNW);
17051705
// Return the expression with the addrec on the outside.
17061706
return getAddRecExpr(
17071707
getExtendAddRecStart<SCEVZeroExtendExpr>(AR, Ty, this,
@@ -1730,7 +1730,7 @@ ScalarEvolution::getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
17301730
}
17311731

17321732
if (proveNoWrapByVaryingStart<SCEVZeroExtendExpr>(Start, Step, L)) {
1733-
const_cast<SCEVAddRecExpr *>(AR)->setNoWrapFlags(SCEV::FlagNUW);
1733+
setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNUW);
17341734
return getAddRecExpr(
17351735
getExtendAddRecStart<SCEVZeroExtendExpr>(AR, Ty, this, Depth + 1),
17361736
getZeroExtendExpr(Step, Ty, Depth + 1), L, AR->getNoWrapFlags());
@@ -1929,7 +1929,7 @@ ScalarEvolution::getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
19291929

19301930
if (!AR->hasNoSignedWrap()) {
19311931
auto NewFlags = proveNoWrapViaConstantRanges(AR);
1932-
const_cast<SCEVAddRecExpr *>(AR)->setNoWrapFlags(NewFlags);
1932+
setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), NewFlags);
19331933
}
19341934

19351935
// If we have special knowledge that this addrec won't overflow,
@@ -1978,7 +1978,7 @@ ScalarEvolution::getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
19781978
SCEV::FlagAnyWrap, Depth + 1);
19791979
if (SAdd == OperandExtendedAdd) {
19801980
// Cache knowledge of AR NSW, which is propagated to this AddRec.
1981-
const_cast<SCEVAddRecExpr *>(AR)->setNoWrapFlags(SCEV::FlagNSW);
1981+
setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNSW);
19821982
// Return the expression with the addrec on the outside.
19831983
return getAddRecExpr(
19841984
getExtendAddRecStart<SCEVSignExtendExpr>(AR, Ty, this,
@@ -2003,7 +2003,7 @@ ScalarEvolution::getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
20032003
// Thus (AR is not NW => SAdd != OperandExtendedAdd) <=>
20042004
// (SAdd == OperandExtendedAdd => AR is NW)
20052005

2006-
const_cast<SCEVAddRecExpr *>(AR)->setNoWrapFlags(SCEV::FlagNW);
2006+
setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNW);
20072007

20082008
// Return the expression with the addrec on the outside.
20092009
return getAddRecExpr(
@@ -2037,7 +2037,7 @@ ScalarEvolution::getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
20372037
(isLoopBackedgeGuardedByCond(L, Pred, AR, OverflowLimit) ||
20382038
isKnownOnEveryIteration(Pred, AR, OverflowLimit))) {
20392039
// Cache knowledge of AR NSW, then propagate NSW to the wide AddRec.
2040-
const_cast<SCEVAddRecExpr *>(AR)->setNoWrapFlags(SCEV::FlagNSW);
2040+
setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNSW);
20412041
return getAddRecExpr(
20422042
getExtendAddRecStart<SCEVSignExtendExpr>(AR, Ty, this, Depth + 1),
20432043
getSignExtendExpr(Step, Ty, Depth + 1), L, AR->getNoWrapFlags());
@@ -2062,7 +2062,7 @@ ScalarEvolution::getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
20622062
}
20632063

20642064
if (proveNoWrapByVaryingStart<SCEVSignExtendExpr>(Start, Step, L)) {
2065-
const_cast<SCEVAddRecExpr *>(AR)->setNoWrapFlags(SCEV::FlagNSW);
2065+
setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNSW);
20662066
return getAddRecExpr(
20672067
getExtendAddRecStart<SCEVSignExtendExpr>(AR, Ty, this, Depth + 1),
20682068
getSignExtendExpr(Step, Ty, Depth + 1), L, AR->getNoWrapFlags());
@@ -2732,7 +2732,7 @@ ScalarEvolution::getOrCreateAddRecExpr(ArrayRef<const SCEV *> Ops,
27322732
UniqueSCEVs.InsertNode(S, IP);
27332733
addToLoopUseLists(S);
27342734
}
2735-
S->setNoWrapFlags(Flags);
2735+
setNoWrapFlags(S, Flags);
27362736
return S;
27372737
}
27382738

@@ -5514,6 +5514,15 @@ static Optional<ConstantRange> GetRangeFromMetadata(Value *V) {
55145514
return None;
55155515
}
55165516

5517+
void ScalarEvolution::setNoWrapFlags(SCEVAddRecExpr *AddRec,
5518+
SCEV::NoWrapFlags Flags) {
5519+
if (AddRec->getNoWrapFlags(Flags) != Flags) {
5520+
AddRec->setNoWrapFlags(Flags);
5521+
UnsignedRanges.erase(AddRec);
5522+
SignedRanges.erase(AddRec);
5523+
}
5524+
}
5525+
55175526
/// Determine the range for a particular SCEV. If SignHint is
55185527
/// HINT_RANGE_UNSIGNED (resp. HINT_RANGE_SIGNED) then getRange prefers ranges
55195528
/// with a "cleaner" unsigned (resp. signed) representation.

llvm/test/Analysis/ScalarEvolution/srem.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ define dso_local void @_Z4loopi(i32 %width) local_unnamed_addr #0 {
2929
; CHECK-NEXT: %add = add nsw i32 %2, %call
3030
; CHECK-NEXT: --> (%2 + %call) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }
3131
; CHECK-NEXT: %inc = add nsw i32 %i.0, 1
32-
; CHECK-NEXT: --> {1,+,1}<nuw><%for.cond> U: full-set S: full-set Exits: (1 + %width) LoopDispositions: { %for.cond: Computable }
32+
; CHECK-NEXT: --> {1,+,1}<nuw><%for.cond> U: [1,0) S: [1,0) Exits: (1 + %width) LoopDispositions: { %for.cond: Computable }
3333
; CHECK-NEXT: Determining loop execution counts for: @_Z4loopi
3434
; CHECK-NEXT: Loop %for.cond: backedge-taken count is %width
3535
; CHECK-NEXT: Loop %for.cond: max backedge-taken count is -1

llvm/test/Transforms/IndVarSimplify/floating-point-iv.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ define double @test_max_be() {
150150
; CHECK-NEXT: [[INDVAR_CONV:%.*]] = sitofp i32 [[TMP11_INT]] to double
151151
; CHECK-NEXT: [[TMP12]] = fadd double [[TMP10]], [[INDVAR_CONV]]
152152
; CHECK-NEXT: [[TMP13_INT]] = add nuw nsw i32 [[TMP11_INT]], 1
153-
; CHECK-NEXT: [[TMP14:%.*]] = icmp slt i32 [[TMP13_INT]], 99999
153+
; CHECK-NEXT: [[TMP14:%.*]] = icmp ult i32 [[TMP13_INT]], 99999
154154
; CHECK-NEXT: br i1 [[TMP14]], label [[BB22]], label [[BB6:%.*]]
155155
; CHECK: bb22:
156156
; CHECK-NEXT: br i1 true, label [[BB8]], label [[BB6]]
@@ -189,7 +189,7 @@ define float @test_max_be2() {
189189
; CHECK-NEXT: [[INDVAR_CONV:%.*]] = sitofp i32 [[TMP11_INT]] to float
190190
; CHECK-NEXT: [[TMP12]] = fadd float [[TMP10]], [[INDVAR_CONV]]
191191
; CHECK-NEXT: [[TMP13_INT]] = add nuw nsw i32 [[TMP11_INT]], 1
192-
; CHECK-NEXT: [[TMP14:%.*]] = icmp slt i32 [[TMP13_INT]], 99999
192+
; CHECK-NEXT: [[TMP14:%.*]] = icmp ult i32 [[TMP13_INT]], 99999
193193
; CHECK-NEXT: br i1 [[TMP14]], label [[BB22]], label [[BB6:%.*]]
194194
; CHECK: bb22:
195195
; CHECK-NEXT: br i1 true, label [[BB8]], label [[BB6]]
@@ -229,7 +229,7 @@ define float @test_max_be3() {
229229
; CHECK-NEXT: [[INDVAR_CONV:%.*]] = sitofp i32 [[TMP11_INT]] to float
230230
; CHECK-NEXT: [[TMP12]] = fadd float [[TMP10]], [[INDVAR_CONV]]
231231
; CHECK-NEXT: [[TMP13_INT]] = add nuw nsw i32 [[TMP11_INT]], 1
232-
; CHECK-NEXT: [[TMP14:%.*]] = icmp slt i32 [[TMP13_INT]], 99999
232+
; CHECK-NEXT: [[TMP14:%.*]] = icmp ult i32 [[TMP13_INT]], 99999
233233
; CHECK-NEXT: br i1 [[TMP14]], label [[BB22]], label [[BB6:%.*]]
234234
; CHECK: bb22:
235235
; CHECK-NEXT: br i1 true, label [[BB8]], label [[BB6]]

0 commit comments

Comments
 (0)