[llvm] [SCEV] Set BTC to zero, if constant max BTC < BECountIfTaken. (PR #226098)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 24 03:05:27 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: Florian Hahn (fhahn)

<details>
<summary>Changes</summary>

If ConstantMaxBECount < BECountIfTaken, we know that the backedge is
never taken and BTC is zero.

No changes in https://github.com/dtcxzyw/llvm-opt-benchmark-nightly/pull/1426.
The main motivation is to remove another difference between howManyLessThans
and howManyGreaterThans, which does not have the BECountIfBackedgeTaken
logic and would compute tighter bounds for backedges never taken.

No compile-time impact: https://llvm-compile-time-tracker.com/compare.php?from=022fdfa1e5a0b85dc785d30b17be3880768b22dc&to=475eeff40ba520620a406a3f615d660ed7c3eec0&stat=instructions:u

---
Full diff: https://github.com/llvm/llvm-project/pull/226098.diff


2 Files Affected:

- (modified) llvm/lib/Analysis/ScalarEvolution.cpp (+14-6) 
- (modified) llvm/test/Analysis/ScalarEvolution/trip-count13.ll (+27) 


``````````diff
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index b822b7a5d3927..7b3b822f5939a 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -13824,16 +13824,24 @@ ScalarEvolution::howManyLessThans(const SCEV *LHS, const SCEV *RHS,
   bool MaxOrZero = false;
   if (isa<SCEVConstant>(BECount)) {
     ConstantMaxBECount = BECount;
-  } else if (isa<SCEVConstant>(BECountIfBackedgeTaken)) {
-    // If we know exactly how many times the backedge will be taken if it's
-    // taken at least once, then the backedge count will either be that or
-    // zero.
-    ConstantMaxBECount = BECountIfBackedgeTaken;
-    MaxOrZero = true;
   } else {
     ConstantMaxBECount = computeMaxBECountForLT(
         Start, Stride, RHS, getTypeSizeInBits(LHS->getType()), IsSigned,
         /*Invert=*/false);
+    // If we know exactly how many times the backedge will be taken if it's
+    // taken at least once, then the backedge count will either be that or
+    // zero. If that count exceeds the range-based bound, the backedge can
+    // never be taken.
+    const APInt *IfTaken, *RangeMax;
+    if (match(BECountIfBackedgeTaken, m_scev_APInt(IfTaken))) {
+      if (match(ConstantMaxBECount, m_scev_APInt(RangeMax)) &&
+          IfTaken->ugt(*RangeMax)) {
+        ConstantMaxBECount = getZero(BECountIfBackedgeTaken->getType());
+      } else {
+        ConstantMaxBECount = BECountIfBackedgeTaken;
+        MaxOrZero = true;
+      }
+    }
   }
 
   if (isa<SCEVCouldNotCompute>(ConstantMaxBECount) &&
diff --git a/llvm/test/Analysis/ScalarEvolution/trip-count13.ll b/llvm/test/Analysis/ScalarEvolution/trip-count13.ll
index e3e17a97da639..7b6229f127cd5 100644
--- a/llvm/test/Analysis/ScalarEvolution/trip-count13.ll
+++ b/llvm/test/Analysis/ScalarEvolution/trip-count13.ll
@@ -124,3 +124,30 @@ loop:
 leave:
   ret void
 }
+
+; %start is in [-1, 127], which bounds the backedge-taken count by 128. The
+; backedge-taken count if the backedge is taken at all is 241, so the backedge
+; is never taken.
+define void @s_3(i8 %n) {
+; CHECK-LABEL: 's_3'
+; CHECK-NEXT:  Determining loop execution counts for: @s_3
+; CHECK-NEXT:  Loop %loop: backedge-taken count is i8 0
+; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i8 0
+; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is i8 0
+; CHECK-NEXT:  Loop %loop: Trip multiple is 1
+;
+entry:
+  %start = add nsw i8 %n, 127
+  %rhs = add i8 %n, 112
+  %g = icmp sgt i8 %start, %rhs
+  br i1 %g, label %loop, label %leave
+
+loop:
+  %iv = phi i8 [ %start, %entry ], [ %iv.inc, %loop ]
+  %iv.inc = add i8 %iv, 1
+  %iv.cmp = icmp slt i8 %iv, %rhs
+  br i1 %iv.cmp, label %loop, label %leave
+
+leave:
+  ret void
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/226098


More information about the llvm-commits mailing list