-
Notifications
You must be signed in to change notification settings - Fork 12.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scev assume finite flag #91104
base: main
Are you sure you want to change the base?
Scev assume finite flag #91104
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write If you have received no comments on your PR for a week, you can request a review If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-llvm-analysis Author: Manuel Drehwald (ZuseZ4) Changes@nikic The first of three PRs, as mentioned in #83052 (comment) Full diff: https://github.com/llvm/llvm-project/pull/91104.diff 3 Files Affected:
diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index 5828cc156cc785..0399499a6224e6 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -460,6 +460,9 @@ class ScalarEvolution {
LoopComputable ///< The SCEV varies predictably with the loop.
};
+ bool AssumeLoopFinite = false;
+ void setAssumeLoopExits();
+
/// An enum describing the relationship between a SCEV and a basic block.
enum BlockDisposition {
DoesNotDominateBlock, ///< The SCEV does not dominate the block.
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 93f885c5d5ad8b..2f8bdb3ee366dc 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -509,6 +509,8 @@ const SCEV *ScalarEvolution::getVScale(Type *Ty) {
return S;
}
+void ScalarEvolution::setAssumeLoopExits() { this->AssumeLoopFinite = true; }
+
const SCEV *ScalarEvolution::getElementCount(Type *Ty, ElementCount EC) {
const SCEV *Res = getConstant(Ty, EC.getKnownMinValue());
if (EC.isScalable())
@@ -7422,7 +7424,8 @@ bool ScalarEvolution::loopIsFiniteByAssumption(const Loop *L) {
// A mustprogress loop without side effects must be finite.
// TODO: The check used here is very conservative. It's only *specific*
// side effects which are well defined in infinite loops.
- return isFinite(L) || (isMustProgress(L) && loopHasNoSideEffects(L));
+ return AssumeLoopFinite || isFinite(L) ||
+ (isMustProgress(L) && loopHasNoSideEffects(L));
}
const SCEV *ScalarEvolution::createSCEVIter(Value *V) {
diff --git a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
index a7b3c5c404ab75..24c07096b12b3f 100644
--- a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
+++ b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -1085,6 +1085,36 @@ TEST_F(ScalarEvolutionsTest, SCEVComputeExpressionSize) {
EXPECT_EQ(S2S->getExpressionSize(), 5u);
}
+TEST_F(ScalarEvolutionsTest, AssumeLoopExists) {
+ LLVMContext C;
+ SMDiagnostic Err;
+ std::unique_ptr<Module> M = parseAssemblyString(
+ "define void @foo(i32 %N) { "
+ "entry: "
+ " %cmp3 = icmp sgt i32 %N, 0 "
+ " br i1 %cmp3, label %for.body, label %for.cond.cleanup "
+ "for.cond.cleanup: "
+ " ret void "
+ "for.body: "
+ " br label %for.body "
+ "} "
+ "declare i32 @llvm.loop.decrement.reg.i32.i32.i32(i32, i32) ",
+ Err, C);
+
+ ASSERT_TRUE(M && "Could not parse module?");
+ ASSERT_TRUE(!verifyModule(*M) && "Must have been well formed!");
+
+ runWithSE(*M, "foo", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
+ BasicBlock *L = F.begin()->getNextNode()->getNextNode();
+ auto *Loop = LI.getLoopFor(L);
+ bool IsFinite = SE.loopIsFiniteByAssumption(Loop);
+ EXPECT_FALSE(IsFinite);
+ SE.setAssumeLoopExits();
+ IsFinite = SE.loopIsFiniteByAssumption(Loop);
+ EXPECT_TRUE(IsFinite);
+ });
+}
+
TEST_F(ScalarEvolutionsTest, SCEVLoopDecIntrinsic) {
LLVMContext C;
SMDiagnostic Err;
|
You can test this locally with the following command:git-clang-format --diff 7a484d3a1f630ba9ce7b22e744818be974971470 f10bf0934cbbbdb72c7009b1b5f6b0d7d09ec678 -- llvm/include/llvm/Analysis/ScalarEvolution.h llvm/lib/Analysis/ScalarEvolution.cpp llvm/unittests/Analysis/ScalarEvolutionTest.cpp View the diff from clang-format here.diff --git a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
index f74584636b..f00bc8609c 100644
--- a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
+++ b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -1097,8 +1097,8 @@ TEST_F(ScalarEvolutionsTest, AssumeLoopExists) {
" ret void "
"for.body: "
" br label %for.body "
- "} "
- Err, C);
+ "} " Err,
+ C);
ASSERT_TRUE(M && "Could not parse module?");
ASSERT_TRUE(!verifyModule(*M) && "Must have been well formed!");
|
@ZuseZ4 could you add me as a collaborator, trying to push a fix for the CI failure. |
@nikic The first of three PRs, as mentioned in #83052 (comment)
@skewballfox is busy with some other work, so we discussed that I'll try to finish the upstreaming.