[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