[llvm] Scev assume finite flag (PR #91104)

Manuel Drehwald via llvm-commits llvm-commits at lists.llvm.org
Sat May 4 21:22:53 PDT 2024


https://github.com/ZuseZ4 updated https://github.com/llvm/llvm-project/pull/91104

>From c56585164b1b93717452959aad50cd3138ad8fc3 Mon Sep 17 00:00:00 2001
From: Joshua Ferguson <joshua.ferguson.273 at gmail.com>
Date: Sun, 5 May 2024 00:07:26 -0400
Subject: [PATCH 1/3] adding AssumeLoopExists flag

---
 llvm/include/llvm/Analysis/ScalarEvolution.h | 3 +++
 llvm/lib/Analysis/ScalarEvolution.cpp        | 5 ++++-
 2 files changed, 7 insertions(+), 1 deletion(-)

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) {

>From 0dfb651ca32d2e22ced31fa0416d2d4ff2b395c7 Mon Sep 17 00:00:00 2001
From: Manuel Drehwald <git at manuel.drehwald.info>
Date: Sun, 5 May 2024 00:08:54 -0400
Subject: [PATCH 2/3] add AssumeLoopExists test

---
 .../Analysis/ScalarEvolutionTest.cpp          | 30 +++++++++++++++++++
 1 file changed, 30 insertions(+)

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;

>From f10bf0934cbbbdb72c7009b1b5f6b0d7d09ec678 Mon Sep 17 00:00:00 2001
From: Manuel Drehwald <git at manuel.drehwald.info>
Date: Sun, 5 May 2024 00:22:38 -0400
Subject: [PATCH 3/3] cleanup

---
 llvm/unittests/Analysis/ScalarEvolutionTest.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
index 24c07096b12b3f..f74584636bd155 100644
--- a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
+++ b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -1098,7 +1098,6 @@ TEST_F(ScalarEvolutionsTest, AssumeLoopExists) {
       "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?");



More information about the llvm-commits mailing list