Skip to content

Commit 02ee96e

Browse files
authored
[Analysis] Teach isDereferenceableAndAlignedInLoop about SCEV predicates (#106562)
Currently if a loop contains loads that we can prove at compile time are dereferenceable when certain conditions are satisfied the function isDereferenceableAndAlignedInLoop will still return false because getSmallConstantMaxTripCount will return 0 when SCEV predicates are required. This patch changes getSmallConstantMaxTripCount to take an optional Predicates pointer argument so that we can permit functions such as isDereferenceableAndAlignedInLoop to consider more cases.
1 parent 6fc2451 commit 02ee96e

File tree

13 files changed

+256
-34
lines changed

13 files changed

+256
-34
lines changed

llvm/include/llvm/Analysis/Loads.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ class LoadInst;
2727
class Loop;
2828
class MemoryLocation;
2929
class ScalarEvolution;
30+
class SCEVPredicate;
31+
template <typename T> class SmallVectorImpl;
3032
class TargetLibraryInfo;
3133

3234
/// Return true if this is always a dereferenceable pointer. If the context
@@ -81,14 +83,16 @@ bool isSafeToLoadUnconditionally(Value *V, Align Alignment, const APInt &Size,
8183
/// that required by the header itself and could be hoisted into the header
8284
/// if desired.) This is more powerful than the variants above when the
8385
/// address loaded from is analyzeable by SCEV.
84-
bool isDereferenceableAndAlignedInLoop(LoadInst *LI, Loop *L,
85-
ScalarEvolution &SE, DominatorTree &DT,
86-
AssumptionCache *AC = nullptr);
86+
bool isDereferenceableAndAlignedInLoop(
87+
LoadInst *LI, Loop *L, ScalarEvolution &SE, DominatorTree &DT,
88+
AssumptionCache *AC = nullptr,
89+
SmallVectorImpl<const SCEVPredicate *> *Predicates = nullptr);
8790

8891
/// Return true if the loop \p L cannot fault on any iteration and only
8992
/// contains read-only memory accesses.
90-
bool isDereferenceableReadOnlyLoop(Loop *L, ScalarEvolution *SE,
91-
DominatorTree *DT, AssumptionCache *AC);
93+
bool isDereferenceableReadOnlyLoop(
94+
Loop *L, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC,
95+
SmallVectorImpl<const SCEVPredicate *> *Predicates = nullptr);
9296

9397
/// Return true if we know that executing a load from this value cannot trap.
9498
///

llvm/include/llvm/Analysis/ScalarEvolution.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -823,8 +823,11 @@ class ScalarEvolution {
823823

824824
/// Returns the upper bound of the loop trip count as a normal unsigned
825825
/// value.
826-
/// Returns 0 if the trip count is unknown or not constant.
827-
unsigned getSmallConstantMaxTripCount(const Loop *L);
826+
/// Returns 0 if the trip count is unknown, not constant or requires
827+
/// SCEV predicates and \p Predicates is nullptr.
828+
unsigned getSmallConstantMaxTripCount(
829+
const Loop *L,
830+
SmallVectorImpl<const SCEVPredicate *> *Predicates = nullptr);
828831

829832
/// Returns the largest constant divisor of the trip count as a normal
830833
/// unsigned value, if possible. This means that the actual trip count is
@@ -905,6 +908,13 @@ class ScalarEvolution {
905908
return getBackedgeTakenCount(L, ConstantMaximum);
906909
}
907910

911+
/// Similar to getConstantMaxBackedgeTakenCount, except it will add a set of
912+
/// SCEV predicates to Predicates that are required to be true in order for
913+
/// the answer to be correct. Predicates can be checked with run-time
914+
/// checks and can be used to perform loop versioning.
915+
const SCEV *getPredicatedConstantMaxBackedgeTakenCount(
916+
const Loop *L, SmallVectorImpl<const SCEVPredicate *> &Predicates);
917+
908918
/// When successful, this returns a SCEV that is greater than or equal
909919
/// to (i.e. a "conservative over-approximation") of the value returend by
910920
/// getBackedgeTakenCount. If such a value cannot be computed, it returns the
@@ -1506,7 +1516,7 @@ class ScalarEvolution {
15061516

15071517
/// Expression indicating the least constant maximum backedge-taken count of
15081518
/// the loop that is known, or a SCEVCouldNotCompute. This expression is
1509-
/// only valid if the redicates associated with all loop exits are true.
1519+
/// only valid if the predicates associated with all loop exits are true.
15101520
const SCEV *ConstantMax = nullptr;
15111521

15121522
/// Indicating if \c ExitNotTaken has an element for every exiting block in
@@ -1585,7 +1595,9 @@ class ScalarEvolution {
15851595
}
15861596

15871597
/// Get the constant max backedge taken count for the loop.
1588-
const SCEV *getConstantMax(ScalarEvolution *SE) const;
1598+
const SCEV *getConstantMax(
1599+
ScalarEvolution *SE,
1600+
SmallVectorImpl<const SCEVPredicate *> *Predicates = nullptr) const;
15891601

15901602
/// Get the constant max backedge taken count for the particular loop exit.
15911603
const SCEV *getConstantMax(

llvm/lib/Analysis/Loads.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -276,10 +276,9 @@ static bool AreEquivalentAddressValues(const Value *A, const Value *B) {
276276
return false;
277277
}
278278

279-
bool llvm::isDereferenceableAndAlignedInLoop(LoadInst *LI, Loop *L,
280-
ScalarEvolution &SE,
281-
DominatorTree &DT,
282-
AssumptionCache *AC) {
279+
bool llvm::isDereferenceableAndAlignedInLoop(
280+
LoadInst *LI, Loop *L, ScalarEvolution &SE, DominatorTree &DT,
281+
AssumptionCache *AC, SmallVectorImpl<const SCEVPredicate *> *Predicates) {
283282
auto &DL = LI->getDataLayout();
284283
Value *Ptr = LI->getPointerOperand();
285284

@@ -304,7 +303,7 @@ bool llvm::isDereferenceableAndAlignedInLoop(LoadInst *LI, Loop *L,
304303
if (!Step)
305304
return false;
306305

307-
auto TC = SE.getSmallConstantMaxTripCount(L);
306+
auto TC = SE.getSmallConstantMaxTripCount(L, Predicates);
308307
if (!TC)
309308
return false;
310309

@@ -810,13 +809,13 @@ bool llvm::canReplacePointersIfEqual(const Value *From, const Value *To,
810809
return isPointerAlwaysReplaceable(From, To, DL);
811810
}
812811

813-
bool llvm::isDereferenceableReadOnlyLoop(Loop *L, ScalarEvolution *SE,
814-
DominatorTree *DT,
815-
AssumptionCache *AC) {
812+
bool llvm::isDereferenceableReadOnlyLoop(
813+
Loop *L, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC,
814+
SmallVectorImpl<const SCEVPredicate *> *Predicates) {
816815
for (BasicBlock *BB : L->blocks()) {
817816
for (Instruction &I : *BB) {
818817
if (auto *LI = dyn_cast<LoadInst>(&I)) {
819-
if (!isDereferenceableAndAlignedInLoop(LI, L, *SE, *DT, AC))
818+
if (!isDereferenceableAndAlignedInLoop(LI, L, *SE, *DT, AC, Predicates))
820819
return false;
821820
} else if (I.mayReadFromMemory() || I.mayWriteToMemory() || I.mayThrow())
822821
return false;

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8191,10 +8191,13 @@ ScalarEvolution::getSmallConstantTripCount(const Loop *L,
81918191
return getConstantTripCount(ExitCount);
81928192
}
81938193

8194-
unsigned ScalarEvolution::getSmallConstantMaxTripCount(const Loop *L) {
8194+
unsigned ScalarEvolution::getSmallConstantMaxTripCount(
8195+
const Loop *L, SmallVectorImpl<const SCEVPredicate *> *Predicates) {
8196+
81958197
const auto *MaxExitCount =
8196-
dyn_cast<SCEVConstant>(getConstantMaxBackedgeTakenCount(L));
8197-
return getConstantTripCount(MaxExitCount);
8198+
Predicates ? getPredicatedConstantMaxBackedgeTakenCount(L, *Predicates)
8199+
: getConstantMaxBackedgeTakenCount(L);
8200+
return getConstantTripCount(dyn_cast<SCEVConstant>(MaxExitCount));
81988201
}
81998202

82008203
unsigned ScalarEvolution::getSmallConstantTripMultiple(const Loop *L) {
@@ -8303,6 +8306,11 @@ const SCEV *ScalarEvolution::getPredicatedSymbolicMaxBackedgeTakenCount(
83038306
return getPredicatedBackedgeTakenInfo(L).getSymbolicMax(L, this, &Preds);
83048307
}
83058308

8309+
const SCEV *ScalarEvolution::getPredicatedConstantMaxBackedgeTakenCount(
8310+
const Loop *L, SmallVectorImpl<const SCEVPredicate *> &Preds) {
8311+
return getPredicatedBackedgeTakenInfo(L).getConstantMax(this, &Preds);
8312+
}
8313+
83068314
bool ScalarEvolution::isBackedgeTakenCountMaxOrZero(const Loop *L) {
83078315
return getBackedgeTakenInfo(L).isConstantMaxOrZero(this);
83088316
}
@@ -8624,15 +8632,19 @@ ScalarEvolution::BackedgeTakenInfo::getExitNotTaken(
86248632
}
86258633

86268634
/// getConstantMax - Get the constant max backedge taken count for the loop.
8627-
const SCEV *
8628-
ScalarEvolution::BackedgeTakenInfo::getConstantMax(ScalarEvolution *SE) const {
8629-
auto PredicateNotAlwaysTrue = [](const ExitNotTakenInfo &ENT) {
8630-
return !ENT.hasAlwaysTruePredicate();
8631-
};
8632-
8633-
if (!getConstantMax() || any_of(ExitNotTaken, PredicateNotAlwaysTrue))
8635+
const SCEV *ScalarEvolution::BackedgeTakenInfo::getConstantMax(
8636+
ScalarEvolution *SE,
8637+
SmallVectorImpl<const SCEVPredicate *> *Predicates) const {
8638+
if (!getConstantMax())
86348639
return SE->getCouldNotCompute();
86358640

8641+
for (const auto &ENT : ExitNotTaken)
8642+
if (!ENT.hasAlwaysTruePredicate()) {
8643+
if (!Predicates)
8644+
return SE->getCouldNotCompute();
8645+
append_range(*Predicates, ENT.Predicates);
8646+
}
8647+
86368648
assert((isa<SCEVCouldNotCompute>(getConstantMax()) ||
86378649
isa<SCEVConstant>(getConstantMax())) &&
86388650
"No point in having a non-constant max backedge taken count!");
@@ -13749,8 +13761,28 @@ static void PrintLoopInfo(raw_ostream &OS, ScalarEvolution *SE,
1374913761
for (const auto *P : Preds)
1375013762
P->print(OS, 4);
1375113763
}
13764+
Preds.clear();
1375213765

13766+
auto *PredConstantMax =
13767+
SE->getPredicatedConstantMaxBackedgeTakenCount(L, Preds);
13768+
if (PredConstantMax != ConstantBTC) {
13769+
assert(!Preds.empty() &&
13770+
"different predicated constant max BTC but no predicates");
13771+
OS << "Loop ";
13772+
L->getHeader()->printAsOperand(OS, /*PrintType=*/false);
13773+
OS << ": ";
13774+
if (!isa<SCEVCouldNotCompute>(PredConstantMax)) {
13775+
OS << "Predicated constant max backedge-taken count is ";
13776+
PrintSCEVWithTypeHint(OS, PredConstantMax);
13777+
} else
13778+
OS << "Unpredictable predicated constant max backedge-taken count.";
13779+
OS << "\n";
13780+
OS << " Predicates:\n";
13781+
for (const auto *P : Preds)
13782+
P->print(OS, 4);
13783+
}
1375313784
Preds.clear();
13785+
1375413786
auto *PredSymbolicMax =
1375513787
SE->getPredicatedSymbolicMaxBackedgeTakenCount(L, Preds);
1375613788
if (SymbolicBTC != PredSymbolicMax) {

llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,11 +1334,17 @@ bool LoopVectorizationLegality::canVectorizeWithIfConvert() {
13341334
// we restrict this to loads; stores are more complicated due to
13351335
// concurrency restrictions.
13361336
ScalarEvolution &SE = *PSE.getSE();
1337+
SmallVector<const SCEVPredicate *, 4> Predicates;
13371338
for (Instruction &I : *BB) {
13381339
LoadInst *LI = dyn_cast<LoadInst>(&I);
1340+
// Pass the Predicates pointer to isDereferenceableAndAlignedInLoop so
1341+
// that it will consider loops that need guarding by SCEV checks. The
1342+
// vectoriser will generate these checks if we decide to vectorise.
13391343
if (LI && !LI->getType()->isVectorTy() && !mustSuppressSpeculation(*LI) &&
1340-
isDereferenceableAndAlignedInLoop(LI, TheLoop, SE, *DT, AC))
1344+
isDereferenceableAndAlignedInLoop(LI, TheLoop, SE, *DT, AC,
1345+
&Predicates))
13411346
SafePointers.insert(LI->getPointerOperand());
1347+
Predicates.clear();
13421348
}
13431349
}
13441350

@@ -1564,7 +1570,9 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
15641570
"Expected latch predecessor to be the early exiting block");
15651571

15661572
// TODO: Handle loops that may fault.
1567-
if (!isDereferenceableReadOnlyLoop(TheLoop, PSE.getSE(), DT, AC)) {
1573+
Predicates.clear();
1574+
if (!isDereferenceableReadOnlyLoop(TheLoop, PSE.getSE(), DT, AC,
1575+
&Predicates)) {
15681576
reportVectorizationFailure(
15691577
"Loop may fault",
15701578
"Cannot vectorize potentially faulting early exit loop",

llvm/test/Analysis/ScalarEvolution/exit-count-non-strict.ll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ define void @ule_from_zero_no_nuw(i32 %M, i32 %N) {
109109
; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((zext i32 %N to i64) umin (1 + (zext i32 %M to i64))<nuw><nsw>)
110110
; CHECK-NEXT: Predicates:
111111
; CHECK-NEXT: {0,+,1}<%loop> Added Flags: <nusw>
112+
; CHECK-NEXT: Loop %loop: Predicated constant max backedge-taken count is i64 4294967295
113+
; CHECK-NEXT: Predicates:
114+
; CHECK-NEXT: {0,+,1}<%loop> Added Flags: <nusw>
112115
; CHECK-NEXT: Loop %loop: Predicated symbolic max backedge-taken count is ((zext i32 %N to i64) umin (1 + (zext i32 %M to i64))<nuw><nsw>)
113116
; CHECK-NEXT: Predicates:
114117
; CHECK-NEXT: {0,+,1}<%loop> Added Flags: <nusw>
@@ -238,6 +241,9 @@ define void @sle_from_int_min_no_nsw(i32 %M, i32 %N) {
238241
; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((zext i32 (-2147483648 + %N) to i64) umin (2147483649 + (sext i32 %M to i64))<nsw>)
239242
; CHECK-NEXT: Predicates:
240243
; CHECK-NEXT: {-2147483648,+,1}<%loop> Added Flags: <nssw>
244+
; CHECK-NEXT: Loop %loop: Predicated constant max backedge-taken count is i64 4294967295
245+
; CHECK-NEXT: Predicates:
246+
; CHECK-NEXT: {-2147483648,+,1}<%loop> Added Flags: <nssw>
241247
; CHECK-NEXT: Loop %loop: Predicated symbolic max backedge-taken count is ((zext i32 (-2147483648 + %N) to i64) umin (2147483649 + (sext i32 %M to i64))<nsw>)
242248
; CHECK-NEXT: Predicates:
243249
; CHECK-NEXT: {-2147483648,+,1}<%loop> Added Flags: <nssw>

llvm/test/Analysis/ScalarEvolution/finite-trip-count.ll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ define void @sle_pre_inc_infinite(i32 %len) {
5959
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (0 smax (1 + (sext i32 %len to i64))<nsw>)
6060
; CHECK-NEXT: Predicates:
6161
; CHECK-NEXT: {0,+,1}<%for.body> Added Flags: <nssw>
62+
; CHECK-NEXT: Loop %for.body: Predicated constant max backedge-taken count is i64 2147483648
63+
; CHECK-NEXT: Predicates:
64+
; CHECK-NEXT: {0,+,1}<%for.body> Added Flags: <nssw>
6265
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is (0 smax (1 + (sext i32 %len to i64))<nsw>)
6366
; CHECK-NEXT: Predicates:
6467
; CHECK-NEXT: {0,+,1}<%for.body> Added Flags: <nssw>
@@ -130,6 +133,9 @@ define void @ule_pre_inc_infinite(i32 %len) {
130133
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (1 + (zext i32 %len to i64))<nuw><nsw>
131134
; CHECK-NEXT: Predicates:
132135
; CHECK-NEXT: {0,+,1}<%for.body> Added Flags: <nusw>
136+
; CHECK-NEXT: Loop %for.body: Predicated constant max backedge-taken count is i64 4294967296
137+
; CHECK-NEXT: Predicates:
138+
; CHECK-NEXT: {0,+,1}<%for.body> Added Flags: <nusw>
133139
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is (1 + (zext i32 %len to i64))<nuw><nsw>
134140
; CHECK-NEXT: Predicates:
135141
; CHECK-NEXT: {0,+,1}<%for.body> Added Flags: <nusw>

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,9 @@ define void @test_zext(i64 %N) mustprogress {
240240
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (%N /u 2)
241241
; CHECK-NEXT: Predicates:
242242
; CHECK-NEXT: {0,+,2}<nuw><%for.body> Added Flags: <nusw>
243+
; CHECK-NEXT: Loop %for.body: Predicated constant max backedge-taken count is i64 9223372036854775807
244+
; CHECK-NEXT: Predicates:
245+
; CHECK-NEXT: {0,+,2}<nuw><%for.body> Added Flags: <nusw>
243246
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is (%N /u 2)
244247
; CHECK-NEXT: Predicates:
245248
; CHECK-NEXT: {0,+,2}<nuw><%for.body> Added Flags: <nusw>

llvm/test/Analysis/ScalarEvolution/predicated-exit-count.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ define i32 @multiple_exits_with_predicates(ptr %src1, ptr readonly %src2, i32 %e
3030
; CHECK-NEXT: Predicates:
3131
; CHECK-NEXT: {1,+,1}<%for.body> Added Flags: <nusw>
3232
; CHECK-EMPTY:
33+
; CHECK-NEXT: Loop %for.body: Predicated constant max backedge-taken count is i32 1023
34+
; CHECK-NEXT: Predicates:
35+
; CHECK-NEXT: {1,+,1}<%for.body> Added Flags: <nusw>
36+
; CHECK-NEXT: {1,+,1}<%for.body> Added Flags: <nusw>
3337
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is (1023 umin (-1 + (1 umax %end)))
3438
; CHECK-NEXT: Predicates:
3539
; CHECK-NEXT: {1,+,1}<%for.body> Added Flags: <nusw>

llvm/test/Analysis/ScalarEvolution/predicated-symbolic-max-backedge-taken-count.ll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ define void @test1(i64 %x, ptr %a, ptr %b) {
2020
; CHECK-NEXT: Predicates:
2121
; CHECK-NEXT: {1,+,1}<%header> Added Flags: <nusw>
2222
; CHECK-EMPTY:
23+
; CHECK-NEXT: Loop %header: Predicated constant max backedge-taken count is i64 -2
24+
; CHECK-NEXT: Predicates:
25+
; CHECK-NEXT: {1,+,1}<%header> Added Flags: <nusw>
2326
; CHECK-NEXT: Loop %header: Predicated symbolic max backedge-taken count is (-1 + (1 umax %x))
2427
; CHECK-NEXT: Predicates:
2528
; CHECK-NEXT: {1,+,1}<%header> Added Flags: <nusw>
@@ -71,6 +74,9 @@ define void @test2(i64 %x, ptr %a) {
7174
; CHECK-NEXT: Predicates:
7275
; CHECK-NEXT: {1,+,1}<%header> Added Flags: <nusw>
7376
; CHECK-EMPTY:
77+
; CHECK-NEXT: Loop %header: Predicated constant max backedge-taken count is i64 -2
78+
; CHECK-NEXT: Predicates:
79+
; CHECK-NEXT: {1,+,1}<%header> Added Flags: <nusw>
7480
; CHECK-NEXT: Loop %header: Predicated symbolic max backedge-taken count is (-1 + (1 umax %x))
7581
; CHECK-NEXT: Predicates:
7682
; CHECK-NEXT: {1,+,1}<%header> Added Flags: <nusw>

llvm/test/Analysis/ScalarEvolution/trip-count-implied-addrec.ll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ define void @nw_implies_nsw(i16 %n) mustprogress {
6161
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (128 + (-128 smax %n))
6262
; CHECK-NEXT: Predicates:
6363
; CHECK-NEXT: {-128,+,1}<%for.body> Added Flags: <nssw>
64+
; CHECK-NEXT: Loop %for.body: Predicated constant max backedge-taken count is i16 -32641
65+
; CHECK-NEXT: Predicates:
66+
; CHECK-NEXT: {-128,+,1}<%for.body> Added Flags: <nssw>
6467
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is (128 + (-128 smax %n))
6568
; CHECK-NEXT: Predicates:
6669
; CHECK-NEXT: {-128,+,1}<%for.body> Added Flags: <nssw>
@@ -110,6 +113,9 @@ define void @actually_infinite() {
110113
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is i16 257
111114
; CHECK-NEXT: Predicates:
112115
; CHECK-NEXT: {0,+,1}<%for.body> Added Flags: <nusw>
116+
; CHECK-NEXT: Loop %for.body: Predicated constant max backedge-taken count is i16 257
117+
; CHECK-NEXT: Predicates:
118+
; CHECK-NEXT: {0,+,1}<%for.body> Added Flags: <nusw>
113119
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is i16 257
114120
; CHECK-NEXT: Predicates:
115121
; CHECK-NEXT: {0,+,1}<%for.body> Added Flags: <nusw>
@@ -138,6 +144,9 @@ define void @rhs_mustexit_1(i16 %n.raw) mustprogress {
138144
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (-1 + (1 umax (-1 + (zext i8 (trunc i16 %n.raw to i8) to i16))<nsw>))
139145
; CHECK-NEXT: Predicates:
140146
; CHECK-NEXT: {1,+,1}<nw><%for.body> Added Flags: <nusw>
147+
; CHECK-NEXT: Loop %for.body: Predicated constant max backedge-taken count is i16 -2
148+
; CHECK-NEXT: Predicates:
149+
; CHECK-NEXT: {1,+,1}<nw><%for.body> Added Flags: <nusw>
141150
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is (-1 + (1 umax (-1 + (zext i8 (trunc i16 %n.raw to i8) to i16))<nsw>))
142151
; CHECK-NEXT: Predicates:
143152
; CHECK-NEXT: {1,+,1}<nw><%for.body> Added Flags: <nusw>
@@ -266,6 +275,9 @@ define void @neg_rhs_maybe_infinite(i16 %n.raw) {
266275
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (-1 + (1 umax (-1 + (zext i8 (trunc i16 %n.raw to i8) to i16))<nsw>))
267276
; CHECK-NEXT: Predicates:
268277
; CHECK-NEXT: {1,+,1}<%for.body> Added Flags: <nusw>
278+
; CHECK-NEXT: Loop %for.body: Predicated constant max backedge-taken count is i16 -2
279+
; CHECK-NEXT: Predicates:
280+
; CHECK-NEXT: {1,+,1}<%for.body> Added Flags: <nusw>
269281
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is (-1 + (1 umax (-1 + (zext i8 (trunc i16 %n.raw to i8) to i16))<nsw>))
270282
; CHECK-NEXT: Predicates:
271283
; CHECK-NEXT: {1,+,1}<%for.body> Added Flags: <nusw>
@@ -391,6 +403,9 @@ define void @ult_constant_rhs_stride2_neg(i16 %n.raw, i8 %start) {
391403
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is ((256 + (-1 * (zext i8 (2 + %start) to i16))<nsw>)<nsw> /u 2)
392404
; CHECK-NEXT: Predicates:
393405
; CHECK-NEXT: {(2 + %start),+,2}<%for.body> Added Flags: <nusw>
406+
; CHECK-NEXT: Loop %for.body: Predicated constant max backedge-taken count is i16 128
407+
; CHECK-NEXT: Predicates:
408+
; CHECK-NEXT: {(2 + %start),+,2}<%for.body> Added Flags: <nusw>
394409
; CHECK-NEXT: Loop %for.body: Predicated symbolic max backedge-taken count is ((256 + (-1 * (zext i8 (2 + %start) to i16))<nsw>)<nsw> /u 2)
395410
; CHECK-NEXT: Predicates:
396411
; CHECK-NEXT: {(2 + %start),+,2}<%for.body> Added Flags: <nusw>

0 commit comments

Comments
 (0)