[llvm] [SCEV] Strip dead code in proving RHS > Start in howManyLT (NFC) (PR #222878)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 11 07:07:09 PDT 2026


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

>From c28ea6509dd1610520e6197d73736f743e989b16 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Fri, 11 Sep 2026 09:06:22 +0100
Subject: [PATCH 1/2] [SCEV] Strip dead code in proving RHS > Start in
 howManyLT (NFC)

isLoopEntryGuardedByCond already handles the case.
---
 llvm/lib/Analysis/ScalarEvolution.cpp | 19 ++-----------------
 1 file changed, 2 insertions(+), 17 deletions(-)

diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 06f350fd2179b..9e32cb68d043c 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -13723,23 +13723,8 @@ ScalarEvolution::howManyLessThans(const SCEV *LHS, const SCEV *RHS,
         const SCEV *GuardedRHS = applyLoopGuards(OrigRHS, L);
         const SCEV *GuardedStart = applyLoopGuards(OrigStart, L);
 
-        if (isLoopEntryGuardedByCond(L, CondGE, OrigRHS, OrigStart) ||
-            isKnownPredicate(CondGE, GuardedRHS, GuardedStart))
-          return true;
-
-        // (RHS > Start - 1) implies RHS >= Start.
-        // * "RHS >= Start" is trivially equivalent to "RHS > Start - 1" if
-        //   "Start - 1" doesn't overflow.
-        // * For signed comparison, if Start - 1 does overflow, it's equal
-        //   to INT_MAX, and "RHS >s INT_MAX" is trivially false.
-        // * For unsigned comparison, if Start - 1 does overflow, it's equal
-        //   to UINT_MAX, and "RHS >u UINT_MAX" is trivially false.
-        //
-        // FIXME: Should isLoopEntryGuardedByCond do this for us?
-        auto CondGT = IsSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
-        auto *StartMinusOne =
-            getAddExpr(OrigStart, getMinusOne(OrigStart->getType()));
-        return isLoopEntryGuardedByCond(L, CondGT, OrigRHS, StartMinusOne);
+        return isLoopEntryGuardedByCond(L, CondGE, OrigRHS, OrigStart) ||
+               isKnownPredicate(CondGE, GuardedRHS, GuardedStart);
       };
 
       // If we know that RHS >= Start in the context of loop, then we know

>From d8b02133184f2930c155f37feb47f652bc22ed89 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Fri, 11 Sep 2026 13:16:07 +0100
Subject: [PATCH 2/2] [SCEV] Use equiv of X >= Y and X > Y - 1 to sharpen
 known-pred

Add a special case for LHS >= RHS in isKnownPredicateWithNoOverflow in
order to sharpen the result.
---
 llvm/lib/Analysis/ScalarEvolution.cpp | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 9e32cb68d043c..7c67ce27f40e8 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -11754,6 +11754,12 @@ bool ScalarEvolution::isKnownPredicateViaNoOverflow(CmpPredicate Pred,
     break;
 
   case ICmpInst::ICMP_SGE:
+    // X s>= Y is equivalent to X s> Y - 1, and this holds trivially when Y - 1
+    // does not overflow. When it does overflow, it must be SINT_MAX, and the
+    // comparison would evaluate to false anyway.
+    if (MatchBinaryAddToConst(LHS, RHS, C1, C2, SCEV::FlagNSW) && C2.isZero() &&
+        C1.sgt(APInt::getAllOnes(C2.getBitWidth())))
+      return true;
     std::swap(LHS, RHS);
     [[fallthrough]];
   case ICmpInst::ICMP_SLE:
@@ -11774,6 +11780,12 @@ bool ScalarEvolution::isKnownPredicateViaNoOverflow(CmpPredicate Pred,
     break;
 
   case ICmpInst::ICMP_UGE:
+    // X u>= Y is equivalent to X u> Y - 1, and this holds trivially when Y - 1
+    // does not overflow. When it does overflow, it must be UINT_MAX, and the
+    // comparison would evaluate to false anyway.
+    if (MatchBinaryAddToConst(LHS, RHS, C1, C2, SCEV::FlagNUW) && C2.isZero() &&
+        C1.ugt(APInt::getAllOnes(C2.getBitWidth())))
+      return true;
     std::swap(LHS, RHS);
     [[fallthrough]];
   case ICmpInst::ICMP_ULE:



More information about the llvm-commits mailing list