Skip to content

Commit 797da79

Browse files
committed
[LoopUtils] Add isKnownPositiveInLoop and isKnownNonPositiveInLoop functions
1 parent 7e5b10b commit 797da79

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

llvm/include/llvm/Transforms/Utils/LoopUtils.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,14 @@ bool isKnownNegativeInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE);
429429
/// loop \p L.
430430
bool isKnownNonNegativeInLoop(const SCEV *S, const Loop *L,
431431
ScalarEvolution &SE);
432+
/// Returns true if we can prove that \p S is defined and always positive in
433+
/// loop \p L.
434+
bool isKnownPositiveInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE);
435+
436+
/// Returns true if we can prove that \p S is defined and always non-positive in
437+
/// loop \p L.
438+
bool isKnownNonPositiveInLoop(const SCEV *S, const Loop *L,
439+
ScalarEvolution &SE);
432440

433441
/// Returns true if \p S is defined and never is equal to signed/unsigned max.
434442
bool cannotBeMaxInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE,

llvm/lib/Transforms/Utils/LoopUtils.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,20 @@ bool llvm::isKnownNonNegativeInLoop(const SCEV *S, const Loop *L,
11361136
SE.isLoopEntryGuardedByCond(L, ICmpInst::ICMP_SGE, S, Zero);
11371137
}
11381138

1139+
bool llvm::isKnownPositiveInLoop(const SCEV *S, const Loop *L,
1140+
ScalarEvolution &SE) {
1141+
const SCEV *Zero = SE.getZero(S->getType());
1142+
return SE.isAvailableAtLoopEntry(S, L) &&
1143+
SE.isLoopEntryGuardedByCond(L, ICmpInst::ICMP_SGT, S, Zero);
1144+
}
1145+
1146+
bool llvm::isKnownNonPositiveInLoop(const SCEV *S, const Loop *L,
1147+
ScalarEvolution &SE) {
1148+
const SCEV *Zero = SE.getZero(S->getType());
1149+
return SE.isAvailableAtLoopEntry(S, L) &&
1150+
SE.isLoopEntryGuardedByCond(L, ICmpInst::ICMP_SLE, S, Zero);
1151+
}
1152+
11391153
bool llvm::cannotBeMinInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE,
11401154
bool Signed) {
11411155
unsigned BitWidth = cast<IntegerType>(S->getType())->getBitWidth();

llvm/unittests/Transforms/Utils/LoopUtilsTest.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,51 @@ TEST(LoopUtils, DeleteDeadLoopNest) {
9393
EXPECT_EQ(BI->getSuccessor(0)->getName(), "for.end");
9494
});
9595
}
96+
97+
TEST(LoopUtils, IsKnownPositiveInLoopTest) {
98+
LLVMContext C;
99+
std::unique_ptr<Module> M =
100+
parseIR(C, "define void @foo(i32 %n, i1 %c) {\n"
101+
"entry:\n"
102+
" %is.positive = icmp sgt i32 %n, 0\n"
103+
" br i1 %is.positive, label %loop, label %exit\n"
104+
"loop:\n"
105+
" br i1 %c, label %loop, label %exit\n"
106+
"exit:\n"
107+
" ret void\n"
108+
"}\n");
109+
110+
run(*M, "foo",
111+
[&](Function &F, DominatorTree &DT, ScalarEvolution &SE, LoopInfo &LI) {
112+
assert(LI.begin() != LI.end() && "Expecting loops in function F");
113+
Loop *L = *LI.begin();
114+
assert(L && L->getName() == "loop" && "Expecting loop 'loop'");
115+
auto *Arg = F.getArg(0);
116+
auto *ArgSCEV = SE.getSCEV(Arg);
117+
EXPECT_EQ(isKnownPositiveInLoop(ArgSCEV, L, SE), true);
118+
});
119+
}
120+
121+
TEST(LoopUtils, IsKnownNonPositiveInLoopTest) {
122+
LLVMContext C;
123+
std::unique_ptr<Module> M =
124+
parseIR(C, "define void @foo(i32 %n, i1 %c) {\n"
125+
"entry:\n"
126+
" %is.non.positive = icmp sle i32 %n, 0\n"
127+
" br i1 %is.non.positive, label %loop, label %exit\n"
128+
"loop:\n"
129+
" br i1 %c, label %loop, label %exit\n"
130+
"exit:\n"
131+
" ret void\n"
132+
"}\n");
133+
134+
run(*M, "foo",
135+
[&](Function &F, DominatorTree &DT, ScalarEvolution &SE, LoopInfo &LI) {
136+
assert(LI.begin() != LI.end() && "Expecting loops in function F");
137+
Loop *L = *LI.begin();
138+
assert(L && L->getName() == "loop" && "Expecting loop 'loop'");
139+
auto *Arg = F.getArg(0);
140+
auto *ArgSCEV = SE.getSCEV(Arg);
141+
EXPECT_EQ(isKnownNonPositiveInLoop(ArgSCEV, L, SE), true);
142+
});
143+
}

0 commit comments

Comments
 (0)