[llvm] d7e4505 - [SCEV] Extend cache-lookup for AR (NFC) (#218927)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 1 00:56:29 PDT 2026


Author: Ramkumar Ramachandra
Date: 2026-10-01T07:56:20Z
New Revision: d7e4505dd447d115d85fdea45cd71030ac1d86ee

URL: https://github.com/llvm/llvm-project/commit/d7e4505dd447d115d85fdea45cd71030ac1d86ee
DIFF: https://github.com/llvm/llvm-project/commit/d7e4505dd447d115d85fdea45cd71030ac1d86ee.diff

LOG: [SCEV] Extend cache-lookup for AR (NFC) (#218927)

It allows us to improve some code, but it cannot be used in getAR
without making functional changes.

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/ScalarEvolution.h
    llvm/lib/Analysis/ScalarEvolution.cpp
    llvm/test/Analysis/ScalarEvolution/addrec-computed-during-addrec-calculation.ll

Removed: 
    


################################################################################
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);
 }

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
+}


        


More information about the llvm-commits mailing list