Skip to content
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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Scev assume finite flag #91104

wants to merge 3 commits into from

Conversation

ZuseZ4
Copy link

@ZuseZ4 ZuseZ4 commented May 5, 2024

@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.

@ZuseZ4 ZuseZ4 requested a review from nikic as a code owner May 5, 2024 04:17
Copy link

github-actions bot commented May 5, 2024

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be
notified.

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
permissions for the repository. In which case you can instead tag reviewers by
name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review
by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate
is once a week. Please remember that you are asking for valuable time from other developers.

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.

@llvmbot
Copy link
Collaborator

llvmbot commented May 5, 2024

@llvm/pr-subscribers-llvm-analysis

Author: Manuel Drehwald (ZuseZ4)

Changes

@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.


Full diff: https://github.com/llvm/llvm-project/pull/91104.diff

3 Files Affected:

  • (modified) llvm/include/llvm/Analysis/ScalarEvolution.h (+3)
  • (modified) llvm/lib/Analysis/ScalarEvolution.cpp (+4-1)
  • (modified) llvm/unittests/Analysis/ScalarEvolutionTest.cpp (+30)
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;

Copy link

github-actions bot commented May 6, 2024

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

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!");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants