[llvm] [SCEV] Introduce getOrCreateUDivExpr (NFC) (PR #216832)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 05:17:08 PDT 2026


https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/216832

>From 2099f78ccfb3595b550de6e139a42ab5b4dc9a6e Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Mon, 17 Aug 2026 20:17:54 +0100
Subject: [PATCH 1/3] [SCEV] Introduce getOrCreateUDivExpr (NFC)

Avoid error-prone munging SCEVUses in place in getUDivExpr, and allocate
the operands uniformly in a new getOrCreateUDivExpr.
---
 llvm/include/llvm/Analysis/ScalarEvolution.h |  3 ++
 llvm/lib/Analysis/ScalarEvolution.cpp        | 53 ++++++++------------
 2 files changed, 25 insertions(+), 31 deletions(-)

diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index 0d7f9ae298e2a..6e7082b950992 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -2515,6 +2515,9 @@ class ScalarEvolution {
   const SCEV *getOrCreateAddRecExpr(ArrayRef<SCEVUse> Ops, const Loop *L,
                                     SCEV::NoWrapFlags Flags);
 
+  // Get UDiv expression already created or create a new one.
+  const SCEV *getOrCreateUDivExpr(SCEVUse LHS, SCEVUse RHS);
+
   /// Return x if \p Val is f(x) where f is a 1-1 function.
   const SCEV *stripInjectiveFunctions(const SCEV *Val) const;
 
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 27a1a20bcdf79..3da8d4fa3bbc3 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -3098,6 +3098,25 @@ const SCEV *ScalarEvolution::getOrCreateMulExpr(ArrayRef<SCEVUse> Ops,
   return S;
 }
 
+const SCEV *ScalarEvolution::getOrCreateUDivExpr(SCEVUse LHS, SCEVUse RHS) {
+  FoldingSetNodeID ID;
+  ID.AddInteger(scUDivExpr);
+  ID.AddPointer(LHS);
+  ID.AddPointer(RHS);
+  void *IP = nullptr;
+  SCEVUDivExpr *S =
+      static_cast<SCEVUDivExpr *>(UniqueSCEVs.FindNodeOrInsertPos(ID, IP));
+  if (!S) {
+    SCEVUse *O = SCEVAllocator.Allocate<SCEVUse>(2);
+    llvm::uninitialized_copy(ArrayRef<SCEVUse>({LHS, RHS}), O);
+    S = new (SCEVAllocator) SCEVUDivExpr(ID.Intern(SCEVAllocator), LHS, RHS);
+    UniqueSCEVs.InsertNode(S, IP);
+    S->computeAndSetCanonical(*this);
+    registerUser(S, ArrayRef<SCEVUse>({LHS, RHS}));
+  }
+  return S;
+}
+
 static uint64_t umul_ov(uint64_t i, uint64_t j, bool &Overflow) {
   uint64_t k = i*j;
   if (j > 1 && k / j != i) Overflow = true;
@@ -3491,14 +3510,6 @@ const SCEV *ScalarEvolution::getUDivExpr(SCEVUse LHS, SCEVUse RHS) {
   assert(LHS->getType() == RHS->getType() &&
          "SCEVUDivExpr operand types don't match!");
 
-  FoldingSetNodeID ID;
-  ID.AddInteger(scUDivExpr);
-  ID.AddPointer(LHS);
-  ID.AddPointer(RHS);
-  void *IP = nullptr;
-  if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP))
-    return S;
-
   // 0 udiv Y == 0
   if (match(LHS, m_scev_Zero()))
     return LHS;
@@ -3564,19 +3575,8 @@ const SCEV *ScalarEvolution::getUDivExpr(SCEVUse LHS, SCEVUse RHS) {
               const SCEV *NewLHS =
                   getAddRecExpr(NewStart, Step, AR->getLoop(),
                                 NoWrap ? SCEV::FlagNW : SCEV::FlagAnyWrap);
-              if (LHS != NewLHS) {
-                LHS = NewLHS;
-
-                // Reset the ID to include the new LHS, and check if it is
-                // already cached.
-                ID.clear();
-                ID.AddInteger(scUDivExpr);
-                ID.AddPointer(LHS);
-                ID.AddPointer(RHS);
-                IP = nullptr;
-                if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP))
-                  return S;
-              }
+              if (LHS != NewLHS)
+                return getUDivExpr(NewLHS, RHS);
             }
           }
         }
@@ -3700,16 +3700,7 @@ const SCEV *ScalarEvolution::getUDivExpr(SCEVUse LHS, SCEVUse RHS) {
       match(RHS, m_scev_c_NUWMul(m_SCEV(NewRHS), m_SCEVVScale())))
     return getUDivExpr(NewLHS, NewRHS);
 
-  // The Insertion Point (IP) might be invalid by now (due to UniqueSCEVs
-  // changes). Make sure we get a new one.
-  IP = nullptr;
-  if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
-  SCEV *S = new (SCEVAllocator) SCEVUDivExpr(ID.Intern(SCEVAllocator),
-                                             LHS, RHS);
-  UniqueSCEVs.InsertNode(S, IP);
-  S->computeAndSetCanonical(*this);
-  registerUser(S, ArrayRef<SCEVUse>({LHS, RHS}));
-  return S;
+  return getOrCreateUDivExpr(LHS, RHS);
 }
 
 APInt gcd(const SCEVConstant *C1, const SCEVConstant *C2) {

>From 829c03b82bb4ee22280b1d09c164c536b29af5d7 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Mon, 17 Aug 2026 22:34:57 +0100
Subject: [PATCH 2/3] [SCEV] findExistingSCEVInCache, thanks

---
 llvm/lib/Analysis/ScalarEvolution.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 3da8d4fa3bbc3..f6067fe999204 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -3510,6 +3510,10 @@ const SCEV *ScalarEvolution::getUDivExpr(SCEVUse LHS, SCEVUse RHS) {
   assert(LHS->getType() == RHS->getType() &&
          "SCEVUDivExpr operand types don't match!");
 
+  if (SCEV *S =
+          findExistingSCEVInCache(scUDivExpr, ArrayRef<SCEVUse>({LHS, RHS})))
+    return S;
+
   // 0 udiv Y == 0
   if (match(LHS, m_scev_Zero()))
     return LHS;

>From 1759858278b4909cb5d5665f836aba6dfa91b42d Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Tue, 18 Aug 2026 13:16:19 +0100
Subject: [PATCH 3/3] [SCEV] Strip left-over dead code

---
 llvm/lib/Analysis/ScalarEvolution.cpp | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index f6067fe999204..9a9c5945aff7a 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -3104,11 +3104,8 @@ const SCEV *ScalarEvolution::getOrCreateUDivExpr(SCEVUse LHS, SCEVUse RHS) {
   ID.AddPointer(LHS);
   ID.AddPointer(RHS);
   void *IP = nullptr;
-  SCEVUDivExpr *S =
-      static_cast<SCEVUDivExpr *>(UniqueSCEVs.FindNodeOrInsertPos(ID, IP));
+  SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP);
   if (!S) {
-    SCEVUse *O = SCEVAllocator.Allocate<SCEVUse>(2);
-    llvm::uninitialized_copy(ArrayRef<SCEVUse>({LHS, RHS}), O);
     S = new (SCEVAllocator) SCEVUDivExpr(ID.Intern(SCEVAllocator), LHS, RHS);
     UniqueSCEVs.InsertNode(S, IP);
     S->computeAndSetCanonical(*this);



More information about the llvm-commits mailing list