[llvm] [SCEV] Extend cache-lookup for AR (NFC) (PR #218927)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 1 00:13:56 PDT 2026
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/218927
>From c40eeb502859c1881ba3373c3896e765918ab8f6 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Thu, 17 Sep 2026 17:24:36 +0100
Subject: [PATCH 1/2] [SCEV] Add test from Florian, thanks!
---
...drec-computed-during-addrec-calculation.ll | 38 +++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/llvm/test/Analysis/ScalarEvolution/addrec-computed-during-addrec-calculation.ll b/llvm/test/Analysis/ScalarEvolution/addrec-computed-during-addrec-calculation.ll
index 81d7fbe2d0c9e..f30b51162a4e1 100644
--- a/llvm/test/Analysis/ScalarEvolution/addrec-computed-during-addrec-calculation.ll
+++ b/llvm/test/Analysis/ScalarEvolution/addrec-computed-during-addrec-calculation.ll
@@ -64,3 +64,41 @@ loop.latch:
%iv.next = trunc i64 %iv3 to i32
br label %loop.header
}
+
+define void @cached_result(i32 %n) {
+; CHECK-LABEL: 'cached_result'
+; CHECK-NEXT: Classifying expressions for: @cached_result
+; CHECK-NEXT: %b = phi i32 [ 2, %entry ], [ %b.n, %loop ]
+; CHECK-NEXT: --> {2,+,4}<%loop> U: [0,-1) S: [-2147483648,2147483647) Exits: (2 + (4 * ((-2 + (3 umax %n)) /u 2)))<nuw><nsw> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %a = phi i32 [ 1, %entry ], [ %a.n, %loop ]
+; CHECK-NEXT: --> {1,+,2}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: (1 + (2 * ((-2 + (3 umax %n)) /u 2))<nuw>)<nuw><nsw> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %b.n = add i32 %b, 4
+; CHECK-NEXT: --> {6,+,4}<%loop> U: [0,-1) S: [-2147483648,2147483647) Exits: (6 + (4 * ((-2 + (3 umax %n)) /u 2))) LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %a.n = add nsw i32 %a, 2
+; CHECK-NEXT: --> {3,+,2}<nuw><nsw><%loop> U: [3,-2147483648) S: [3,-2147483648) Exits: (3 + (2 * ((-2 + (3 umax %n)) /u 2))<nuw>)<nuw> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %c = add nsw i32 %a, %a
+; CHECK-NEXT: --> {2,+,4}<nuw><%loop> U: [2,-1) S: [-2147483648,2147483647) Exits: (2 + (4 * ((-2 + (3 umax %n)) /u 2)))<nuw><nsw> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %d = add i32 %b, 0
+; CHECK-NEXT: --> {2,+,4}<nuw><%loop> U: [2,-1) S: [-2147483648,2147483647) Exits: (2 + (4 * ((-2 + (3 umax %n)) /u 2)))<nuw><nsw> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: Determining loop execution counts for: @cached_result
+; CHECK-NEXT: Loop %loop: backedge-taken count is ((-2 + (3 umax %n)) /u 2)
+; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 2147483646
+; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-2 + (3 umax %n)) /u 2)
+; CHECK-NEXT: Loop %loop: Trip multiple is 1
+;
+entry:
+ br label %loop
+
+loop:
+ %b = phi i32 [ 2, %entry ], [ %b.n, %loop ]
+ %a = phi i32 [ 1, %entry ], [ %a.n, %loop ]
+ %b.n = add i32 %b, 4
+ %a.n = add nsw i32 %a, 2
+ %c = add nsw i32 %a, %a
+ %d = add i32 %b, 0
+ %cmp = icmp ult i32 %a.n, %n
+ br i1 %cmp, label %loop, label %exit
+
+exit:
+ ret void
+}
>From fb9ca517b0c24c63edcb5e29ac7d0012bc1f77e7 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Wed, 26 Aug 2026 13:34:02 +0100
Subject: [PATCH 2/2] [SCEV] Extend cache-lookup for AR (NFC)
It allows us to improve some code, but it cannot be used in getAR
without making functional changes.
---
llvm/include/llvm/Analysis/ScalarEvolution.h | 8 +++++---
llvm/lib/Analysis/ScalarEvolution.cpp | 18 ++++++++----------
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index f2275513a7db8..8e0af061d82ca 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -2569,9 +2569,11 @@ class ScalarEvolution {
/// an add rec on said loop.
void getUsedLoops(const SCEV *S, SmallPtrSetImpl<const Loop *> &LoopsUsed);
- /// Look for a SCEV expression with type `SCEVType` and operands `Ops` in
- /// `UniqueSCEVs`. Return if found, else nullptr.
- SCEV *findExistingSCEVInCache(SCEVTypes SCEVType, ArrayRef<SCEVUse> Ops);
+ /// Look for a SCEV expression with type \p SCEVType and operands \p Ops in
+ /// UniqueSCEVs. If \p SCEVType is scAddRecExpr, the loop \p L must be passed.
+ /// Return if found, else nullptr.
+ SCEV *findExistingSCEVInCache(SCEVTypes SCEVType, ArrayRef<SCEVUse> Ops,
+ const Loop *L = nullptr);
/// Get reachable blocks in this function, making limited use of SCEV
/// reasoning about conditions.
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 0e111b78048f3..530b1400ae69e 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -1444,15 +1444,8 @@ bool ScalarEvolution::proveNoWrapByVaryingStart(const SCEV *Start,
for (unsigned Delta : {-2, -1, 1, 2}) {
const SCEV *PreStart = getConstant(StartAI - Delta);
-
- FoldingSetNodeID ID;
- ID.AddInteger(scAddRecExpr);
- ID.AddPointer(PreStart);
- ID.AddPointer(Step);
- ID.AddPointer(L);
- FoldingSetInsertToken Token;
- const auto *PreAR =
- static_cast<SCEVAddRecExpr *>(UniqueSCEVs.lookup(ID, Token));
+ const auto *PreAR = static_cast<SCEVAddRecExpr *>(
+ findExistingSCEVInCache(scAddRecExpr, {PreStart, Step}, L));
// Give up if we don't already have the add recurrence we need because
// actually constructing an add recurrence is relatively expensive.
@@ -3867,11 +3860,16 @@ const SCEV *ScalarEvolution::getGEPExpr(SCEVUse BaseExpr,
}
SCEV *ScalarEvolution::findExistingSCEVInCache(SCEVTypes SCEVType,
- ArrayRef<SCEVUse> Ops) {
+ ArrayRef<SCEVUse> Ops,
+ const Loop *L) {
+ assert((SCEVType != scAddRecExpr || L) &&
+ "L must be passed to find existing AddRecs");
FoldingSetNodeID ID;
ID.AddInteger(SCEVType);
for (SCEVUse Op : Ops)
ID.AddPointer(Op.getOpaqueValue());
+ if (L)
+ ID.AddPointer(L);
FoldingSetInsertToken Token;
return UniqueSCEVs.lookup(ID, Token);
}
More information about the llvm-commits
mailing list