[llvm] [SCEV] Avoid redundant ValueExprMap lookups in forgetValue (PR #201573)
Mingjie Xu via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 4 05:47:46 PDT 2026
https://github.com/Enna1 updated https://github.com/llvm/llvm-project/pull/201573
>From 21a5664f792522ad9944f76a75cc977ecb8eafb8 Mon Sep 17 00:00:00 2001
From: Enna1 <xumingjie.enna1 at bytedance.com>
Date: Thu, 4 Jun 2026 18:31:54 +0800
Subject: [PATCH 1/3] [SCEV] Avoid redundant ValueExprMap lookups in
forgetValue
---
llvm/lib/Analysis/ScalarEvolution.cpp | 28 ++++++++++++++++++++++-----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index ddf583082b2de..af093d6c8cbb4 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -8838,13 +8838,31 @@ void ScalarEvolution::forgetValue(Value *V) {
Instruction *I = dyn_cast<Instruction>(V);
if (!I) return;
- // Drop information about expressions based on loop-header PHIs.
- SmallVector<Instruction *, 16> Worklist;
+ SmallVector<std::pair<Instruction *, const SCEV *>, 16> Worklist;
SmallPtrSet<Instruction *, 8> Visited;
SmallVector<SCEVUse, 8> ToForget;
- Worklist.push_back(I);
- Visited.insert(I);
- visitAndClearUsers(Worklist, Visited, ToForget);
+
+ auto PushIntoWorklist = [&](Instruction *UI) {
+ bool IsSCEVable = isSCEVable(UI->getType());
+ bool IsWO = isa<WithOverflowInst>(UI);
+ if ((!IsSCEVable && !IsWO) || !Visited.insert(UI).second)
+ return;
+ const SCEV *S = IsSCEVable ? getExistingSCEV(UI) : nullptr;
+ Worklist.emplace_back(UI, S);
+ };
+
+ PushIntoWorklist(I);
+
+ while (!Worklist.empty()) {
+ auto [Cur, S] = Worklist.pop_back_val();
+ if (S) {
+ ToForget.push_back(S);
+ if (auto *PN = dyn_cast<PHINode>(Cur))
+ ConstantEvolutionLoopExitValue.erase(PN);
+ }
+ for (User *U : Cur->users())
+ PushIntoWorklist(cast<Instruction>(U));
+ }
forgetMemoizedResults(ToForget);
}
>From 2652c5c44ba5ae2217243c90c9ec5bdf1b2e0f48 Mon Sep 17 00:00:00 2001
From: Enna1 <xumingjie.enna1 at bytedance.com>
Date: Thu, 4 Jun 2026 20:41:09 +0800
Subject: [PATCH 2/3] add 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 8504534693281..443a510e88223 100644
--- a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
+++ b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -1669,6 +1669,36 @@ TEST_F(ScalarEvolutionsTest, ForgetValueWithOverflowInst) {
});
}
+TEST_F(ScalarEvolutionsTest, ForgetValueAddChainFolding) {
+ LLVMContext C;
+ SMDiagnostic Err;
+ std::unique_ptr<Module> M = parseAssemblyString(
+ "define i32 @foo(i32 %x) { "
+ " %add1 = add i32 %x, 1 "
+ " %add2 = add i32 %add1, 1 "
+ " %add3 = add i32 %add2, 1 "
+ " ret i32 %add3 "
+ "} ",
+ 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) {
+ auto *Add1 = getInstructionByName(F, "add1");
+ auto *Add2 = getInstructionByName(F, "add2");
+ auto *Add3 = getInstructionByName(F, "add3");
+
+ const SCEV *Add3Scev = SE.getSCEV(Add3);
+ EXPECT_NE(Add3Scev, nullptr);
+ EXPECT_EQ(SE.getExistingSCEV(Add1), nullptr);
+ EXPECT_EQ(SE.getExistingSCEV(Add2), nullptr);
+
+ SE.forgetValue(Add1);
+ EXPECT_EQ(SE.getExistingSCEV(Add3), nullptr);
+ });
+}
+
TEST_F(ScalarEvolutionsTest, ComplexityComparatorIsStrictWeakOrdering) {
// Regression test for a case where caching of equivalent values caused the
// comparator to get inconsistent.
>From ac367618b6209eb40a725b518f38d0ee477d4cc8 Mon Sep 17 00:00:00 2001
From: Enna1 <xumingjie.enna1 at bytedance.com>
Date: Thu, 4 Jun 2026 20:47:15 +0800
Subject: [PATCH 3/3] format
---
llvm/unittests/Analysis/ScalarEvolutionTest.cpp | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
index 443a510e88223..165845042c3bd 100644
--- a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
+++ b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -1672,14 +1672,13 @@ TEST_F(ScalarEvolutionsTest, ForgetValueWithOverflowInst) {
TEST_F(ScalarEvolutionsTest, ForgetValueAddChainFolding) {
LLVMContext C;
SMDiagnostic Err;
- std::unique_ptr<Module> M = parseAssemblyString(
- "define i32 @foo(i32 %x) { "
- " %add1 = add i32 %x, 1 "
- " %add2 = add i32 %add1, 1 "
- " %add3 = add i32 %add2, 1 "
- " ret i32 %add3 "
- "} ",
- Err, C);
+ std::unique_ptr<Module> M = parseAssemblyString("define i32 @foo(i32 %x) { "
+ " %add1 = add i32 %x, 1 "
+ " %add2 = add i32 %add1, 1 "
+ " %add3 = add i32 %add2, 1 "
+ " ret i32 %add3 "
+ "} ",
+ Err, C);
ASSERT_TRUE(M && "Could not parse module?");
ASSERT_TRUE(!verifyModule(*M) && "Must have been well formed!");
More information about the llvm-commits
mailing list