[llvm] [SCEV] Preserve recursion depth when folding zext (PR #202350)

Le Gia Bao via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 8 09:22:44 PDT 2026


https://github.com/L3GiaBao updated https://github.com/llvm/llvm-project/pull/202350

>From 4d9fbd7332f1533f3892f6fb281b8488cd6fce05 Mon Sep 17 00:00:00 2001
From: Le Gia Bao <legiabao7300 at gmail.com>
Date: Mon, 8 Jun 2026 10:10:59 -0400
Subject: [PATCH 1/5] recursion depth

---
 llvm/lib/Analysis/ScalarEvolution.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 98f934fdff08e..be31ca98ca969 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -2819,7 +2819,8 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
           hasFlags(StrengthenNoWrapFlags(this, scAddExpr, {NarrowA, InnerAdd},
                                          SCEV::FlagAnyWrap),
                    SCEV::FlagNUW)) {
-        return getZeroExtendExpr(getAddExpr(NarrowA, InnerAdd), B->getType());
+        return getZeroExtendExpr(getAddExpr(NarrowA, InnerAdd), B->getType(),
+                                 Depth + 1);
       }
     }
   }

>From 39cc9f6394a73226be2ba7dad4d41cc3977e99c2 Mon Sep 17 00:00:00 2001
From: Le Gia Bao <legiabao7300 at gmail.com>
Date: Mon, 8 Jun 2026 10:12:17 -0400
Subject: [PATCH 2/5] reduced crash test

---
 llvm/test/CodeGen/X86/pr201758.ll | 154 ++++++++++++++++++++++++++++++
 1 file changed, 154 insertions(+)
 create mode 100644 llvm/test/CodeGen/X86/pr201758.ll

diff --git a/llvm/test/CodeGen/X86/pr201758.ll b/llvm/test/CodeGen/X86/pr201758.ll
new file mode 100644
index 0000000000000..f749aaa9d2839
--- /dev/null
+++ b/llvm/test/CodeGen/X86/pr201758.ll
@@ -0,0 +1,154 @@
+; RUN: llc -mtriple=x86_64-unknown-linux-gnu --start-before loop-reduce --stop-after loop-reduce %s -o %t
+
+; No check in a crash test.
+
+define i32 @pr201758() {
+entry:
+  br label %for.cond3
+for.cond3:
+  tail call void @llvm.assume(i1 false)
+  br label %while.cond
+while.cond:
+  %k.2 = phi i32 [ 0, %while.cond ], [ 1, %for.cond3 ]
+  br i1 false, label %while.cond.1, label %while.cond
+while.cond.1:
+  %k.2.1 = phi i32 [ %dec.1, %while.cond.1 ], [ %k.2, %while.cond ]
+  %dec.1 = add i32 %k.2.1, 1
+  br i1 false, label %while.cond.2, label %while.cond.1
+while.cond.2:
+  %k.2.2 = phi i32 [ %dec.2, %while.cond.2 ], [ %k.2.1, %while.cond.1 ]
+  %dec.2 = add i32 %k.2.2, 1
+  br i1 false, label %while.cond.3, label %while.cond.2
+while.cond.3:
+  %k.2.3 = phi i32 [ %dec.3, %while.cond.3 ], [ %k.2.2, %while.cond.2 ]
+  %dec.3 = add i32 %k.2.3, 1
+  br i1 false, label %while.cond.4, label %while.cond.3
+while.cond.4:
+  %k.2.4 = phi i32 [ %dec.4, %while.cond.4 ], [ %k.2.3, %while.cond.3 ]
+  %dec.4 = add i32 %k.2.4, 1
+  br i1 false, label %while.cond.5, label %while.cond.4
+while.cond.5:
+  %k.2.5 = phi i32 [ %dec.5, %while.cond.5 ], [ %k.2.4, %while.cond.4 ]
+  %dec.5 = add i32 %k.2.5, 1
+  br i1 false, label %while.cond.115, label %while.cond.5
+while.cond.115:
+  %k.2.112 = phi i32 [ %dec.114, %while.cond.115 ], [ %k.2.5, %while.cond.5 ]
+  %dec.114 = add i32 %k.2.112, 1
+  br i1 false, label %while.cond.1.1, label %while.cond.115
+while.cond.1.1:
+  %k.2.1.1 = phi i32 [ %dec.1.1, %while.cond.1.1 ], [ %k.2.112, %while.cond.115 ]
+  %dec.1.1 = add i32 %k.2.1.1, 1
+  br i1 false, label %while.cond.2.1, label %while.cond.1.1
+while.cond.2.1:
+  %k.2.2.1 = phi i32 [ %dec.2.1, %while.cond.2.1 ], [ %k.2.1.1, %while.cond.1.1 ]
+  %dec.2.1 = add i32 %k.2.2.1, 1
+  br i1 false, label %while.cond.3.1, label %while.cond.2.1
+while.cond.3.1:
+  %k.2.3.1 = phi i32 [ %dec.3.1, %while.cond.3.1 ], [ %k.2.2.1, %while.cond.2.1 ]
+  %dec.3.1 = add i32 %k.2.3.1, 1
+  br i1 false, label %while.cond.4.1, label %while.cond.3.1
+while.cond.4.1:
+  %k.2.4.1 = phi i32 [ %dec.4.1, %while.cond.4.1 ], [ %k.2.3.1, %while.cond.3.1 ]
+  %dec.4.1 = add i32 %k.2.4.1, 1
+  br i1 false, label %while.cond.5.1, label %while.cond.4.1
+while.cond.5.1:
+  %k.2.5.1 = phi i32 [ %dec.5.1, %while.cond.5.1 ], [ %k.2.4.1, %while.cond.4.1 ]
+  %dec.5.1 = add i32 %k.2.5.1, 1
+  br i1 false, label %while.cond.221, label %while.cond.5.1
+while.cond.221:
+  %k.2.218 = phi i32 [ %dec.220, %while.cond.221 ], [ %k.2.5.1, %while.cond.5.1 ]
+  %dec.220 = add i32 %k.2.218, 1
+  br i1 false, label %while.cond.1.2, label %while.cond.221
+while.cond.1.2:
+  %k.2.1.2 = phi i32 [ %dec.1.2, %while.cond.1.2 ], [ %k.2.218, %while.cond.221 ]
+  %dec.1.2 = add i32 %k.2.1.2, 1
+  br i1 false, label %while.cond.2.2, label %while.cond.1.2
+while.cond.2.2:
+  %k.2.2.2 = phi i32 [ %dec.2.2, %while.cond.2.2 ], [ %k.2.1.2, %while.cond.1.2 ]
+  %dec.2.2 = add i32 %k.2.2.2, 1
+  br i1 false, label %while.cond.3.2, label %while.cond.2.2
+while.cond.3.2:
+  %k.2.3.2 = phi i32 [ %dec.3.2, %while.cond.3.2 ], [ %k.2.2.2, %while.cond.2.2 ]
+  %dec.3.2 = add i32 %k.2.3.2, 1
+  br i1 false, label %while.cond.4.2, label %while.cond.3.2
+while.cond.4.2:
+  %k.2.4.2 = phi i32 [ %dec.4.2, %while.cond.4.2 ], [ %k.2.3.2, %while.cond.3.2 ]
+  %dec.4.2 = add i32 %k.2.4.2, 1
+  br i1 false, label %while.cond.5.2, label %while.cond.4.2
+while.cond.5.2:
+  %k.2.5.2 = phi i32 [ %dec.5.2, %while.cond.5.2 ], [ %k.2.4.2, %while.cond.4.2 ]
+  %dec.5.2 = add i32 %k.2.5.2, 1
+  br i1 false, label %while.cond.327, label %while.cond.5.2
+while.cond.327:
+  %k.2.324 = phi i32 [ %dec.326, %while.cond.327 ], [ %k.2.5.2, %while.cond.5.2 ]
+  %dec.326 = add i32 %k.2.324, 1
+  br i1 false, label %while.cond.1.3, label %while.cond.327
+while.cond.1.3:
+  %k.2.1.3 = phi i32 [ %dec.1.3, %while.cond.1.3 ], [ %k.2.324, %while.cond.327 ]
+  %dec.1.3 = add i32 %k.2.1.3, 1
+  br i1 false, label %while.cond.2.3, label %while.cond.1.3
+while.cond.2.3:
+  %k.2.2.3 = phi i32 [ %dec.2.3, %while.cond.2.3 ], [ %k.2.1.3, %while.cond.1.3 ]
+  %dec.2.3 = add i32 %k.2.2.3, 1
+  br i1 false, label %while.cond.3.3, label %while.cond.2.3
+while.cond.3.3:
+  %k.2.3.3 = phi i32 [ %dec.3.3, %while.cond.3.3 ], [ %k.2.2.3, %while.cond.2.3 ]
+  %dec.3.3 = add i32 %k.2.3.3, 1
+  br i1 false, label %while.cond.4.3, label %while.cond.3.3
+while.cond.4.3:
+  %k.2.4.3 = phi i32 [ %dec.4.3, %while.cond.4.3 ], [ %k.2.3.3, %while.cond.3.3 ]
+  %dec.4.3 = add i32 %k.2.4.3, 1
+  br i1 false, label %while.cond.5.3, label %while.cond.4.3
+while.cond.5.3:
+  %k.2.5.3 = phi i32 [ %dec.5.3, %while.cond.5.3 ], [ %k.2.4.3, %while.cond.4.3 ]
+  %dec.5.3 = add i32 %k.2.5.3, 1
+  br i1 false, label %while.cond.433, label %while.cond.5.3
+while.cond.433:
+  %k.2.430 = phi i32 [ %dec.432, %while.cond.433 ], [ %k.2.5.3, %while.cond.5.3 ]
+  %dec.432 = add i32 %k.2.430, 1
+  br i1 false, label %while.cond.1.4, label %while.cond.433
+while.cond.1.4:
+  %k.2.1.4 = phi i32 [ %dec.1.4, %while.cond.1.4 ], [ %k.2.430, %while.cond.433 ]
+  %dec.1.4 = add i32 %k.2.1.4, 1
+  br i1 false, label %while.cond.2.4, label %while.cond.1.4
+while.cond.2.4:
+  %k.2.2.4 = phi i32 [ %dec.2.4, %while.cond.2.4 ], [ %k.2.1.4, %while.cond.1.4 ]
+  %dec.2.4 = add i32 %k.2.2.4, 1
+  br i1 false, label %while.cond.3.4, label %while.cond.2.4
+while.cond.3.4:
+  %k.2.3.4 = phi i32 [ %dec.3.4, %while.cond.3.4 ], [ %k.2.2.4, %while.cond.2.4 ]
+  %dec.3.4 = add i32 %k.2.3.4, 1
+  br i1 false, label %while.cond.4.4, label %while.cond.3.4
+while.cond.4.4:
+  %k.2.4.4 = phi i32 [ %dec.4.4, %while.cond.4.4 ], [ %k.2.3.4, %while.cond.3.4 ]
+  %dec.4.4 = add i32 %k.2.4.4, 1
+  br i1 false, label %while.cond.5.4, label %while.cond.4.4
+while.cond.5.4:
+  %k.2.5.4 = phi i32 [ %dec.5.4, %while.cond.5.4 ], [ %k.2.4.4, %while.cond.4.4 ]
+  %dec.5.4 = add i32 %k.2.5.4, 1
+  br i1 false, label %while.cond.539, label %while.cond.5.4
+while.cond.539:
+  %k.2.536 = phi i32 [ %dec.538, %while.cond.539 ], [ %k.2.5.4, %while.cond.5.4 ]
+  %dec.538 = add i32 %k.2.536, 1
+  br i1 false, label %while.cond.1.5, label %while.cond.539
+while.cond.1.5:
+  %k.2.1.5 = phi i32 [ %dec.1.5, %while.cond.1.5 ], [ %k.2.536, %while.cond.539 ]
+  %dec.1.5 = add i32 %k.2.1.5, 1
+  br i1 false, label %while.cond.2.5, label %while.cond.1.5
+while.cond.2.5:
+  %k.2.2.5 = phi i32 [ %dec.2.5, %while.cond.2.5 ], [ %k.2.1.5, %while.cond.1.5 ]
+  %dec.2.5 = add i32 %k.2.2.5, 1
+  br i1 false, label %while.cond.3.5, label %while.cond.2.5
+while.cond.3.5:
+  %k.2.3.5 = phi i32 [ %dec.3.5, %while.cond.3.5 ], [ %k.2.2.5, %while.cond.2.5 ]
+  %dec.3.5 = add i32 %k.2.3.5, -1
+  br i1 false, label %while.cond.4.5, label %while.cond.3.5
+while.cond.4.5:
+  %k.2.4.5 = phi i32 [ %dec.4.5, %while.cond.4.5 ], [ %k.2.3.5, %while.cond.3.5 ]
+  %dec.4.5 = add i32 %k.2.4.5, -1
+  br i1 false, label %while.cond.5.5, label %while.cond.4.5
+while.cond.5.5:
+  store i32 %k.2.4.5, ptr null, align 4
+  br label %for.cond3
+}
+declare void @llvm.assume(i1 noundef)

>From a6d6a6d749992ad36ca831e7f5a316c0c8b1ccce Mon Sep 17 00:00:00 2001
From: Le Gia Bao <legiabao7300 at gmail.com>
Date: Mon, 8 Jun 2026 11:46:41 -0400
Subject: [PATCH 3/5] add depth limits

---
 llvm/lib/Analysis/ScalarEvolution.cpp |   7 +-
 llvm/test/CodeGen/X86/pr201758.ll     | 154 --------------------------
 2 files changed, 4 insertions(+), 157 deletions(-)
 delete mode 100644 llvm/test/CodeGen/X86/pr201758.ll

diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index be31ca98ca969..38c0100855f7c 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -2813,14 +2813,15 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
     // (B), if trunc (A) + -A + B  does not unsigned-wrap.
     const SCEVAddExpr *InnerAdd;
     if (match(B, m_scev_ZExt(m_scev_Add(InnerAdd)))) {
-      const SCEV *NarrowA = getTruncateExpr(A, InnerAdd->getType());
+      const SCEV *NarrowA = getTruncateExpr(A, InnerAdd->getType(), Depth + 1);
       if (NarrowA == getNegativeSCEV(InnerAdd->getOperand(0)) &&
           getZeroExtendExpr(NarrowA, B->getType()) == A &&
           hasFlags(StrengthenNoWrapFlags(this, scAddExpr, {NarrowA, InnerAdd},
                                          SCEV::FlagAnyWrap),
                    SCEV::FlagNUW)) {
-        return getZeroExtendExpr(getAddExpr(NarrowA, InnerAdd), B->getType(),
-                                 Depth + 1);
+        return getZeroExtendExpr(getAddExpr(NarrowA, InnerAdd, SCEV::FlagAnyWrap,
+                                            Depth + 1),
+                                 B->getType(), Depth + 1);
       }
     }
   }
diff --git a/llvm/test/CodeGen/X86/pr201758.ll b/llvm/test/CodeGen/X86/pr201758.ll
deleted file mode 100644
index f749aaa9d2839..0000000000000
--- a/llvm/test/CodeGen/X86/pr201758.ll
+++ /dev/null
@@ -1,154 +0,0 @@
-; RUN: llc -mtriple=x86_64-unknown-linux-gnu --start-before loop-reduce --stop-after loop-reduce %s -o %t
-
-; No check in a crash test.
-
-define i32 @pr201758() {
-entry:
-  br label %for.cond3
-for.cond3:
-  tail call void @llvm.assume(i1 false)
-  br label %while.cond
-while.cond:
-  %k.2 = phi i32 [ 0, %while.cond ], [ 1, %for.cond3 ]
-  br i1 false, label %while.cond.1, label %while.cond
-while.cond.1:
-  %k.2.1 = phi i32 [ %dec.1, %while.cond.1 ], [ %k.2, %while.cond ]
-  %dec.1 = add i32 %k.2.1, 1
-  br i1 false, label %while.cond.2, label %while.cond.1
-while.cond.2:
-  %k.2.2 = phi i32 [ %dec.2, %while.cond.2 ], [ %k.2.1, %while.cond.1 ]
-  %dec.2 = add i32 %k.2.2, 1
-  br i1 false, label %while.cond.3, label %while.cond.2
-while.cond.3:
-  %k.2.3 = phi i32 [ %dec.3, %while.cond.3 ], [ %k.2.2, %while.cond.2 ]
-  %dec.3 = add i32 %k.2.3, 1
-  br i1 false, label %while.cond.4, label %while.cond.3
-while.cond.4:
-  %k.2.4 = phi i32 [ %dec.4, %while.cond.4 ], [ %k.2.3, %while.cond.3 ]
-  %dec.4 = add i32 %k.2.4, 1
-  br i1 false, label %while.cond.5, label %while.cond.4
-while.cond.5:
-  %k.2.5 = phi i32 [ %dec.5, %while.cond.5 ], [ %k.2.4, %while.cond.4 ]
-  %dec.5 = add i32 %k.2.5, 1
-  br i1 false, label %while.cond.115, label %while.cond.5
-while.cond.115:
-  %k.2.112 = phi i32 [ %dec.114, %while.cond.115 ], [ %k.2.5, %while.cond.5 ]
-  %dec.114 = add i32 %k.2.112, 1
-  br i1 false, label %while.cond.1.1, label %while.cond.115
-while.cond.1.1:
-  %k.2.1.1 = phi i32 [ %dec.1.1, %while.cond.1.1 ], [ %k.2.112, %while.cond.115 ]
-  %dec.1.1 = add i32 %k.2.1.1, 1
-  br i1 false, label %while.cond.2.1, label %while.cond.1.1
-while.cond.2.1:
-  %k.2.2.1 = phi i32 [ %dec.2.1, %while.cond.2.1 ], [ %k.2.1.1, %while.cond.1.1 ]
-  %dec.2.1 = add i32 %k.2.2.1, 1
-  br i1 false, label %while.cond.3.1, label %while.cond.2.1
-while.cond.3.1:
-  %k.2.3.1 = phi i32 [ %dec.3.1, %while.cond.3.1 ], [ %k.2.2.1, %while.cond.2.1 ]
-  %dec.3.1 = add i32 %k.2.3.1, 1
-  br i1 false, label %while.cond.4.1, label %while.cond.3.1
-while.cond.4.1:
-  %k.2.4.1 = phi i32 [ %dec.4.1, %while.cond.4.1 ], [ %k.2.3.1, %while.cond.3.1 ]
-  %dec.4.1 = add i32 %k.2.4.1, 1
-  br i1 false, label %while.cond.5.1, label %while.cond.4.1
-while.cond.5.1:
-  %k.2.5.1 = phi i32 [ %dec.5.1, %while.cond.5.1 ], [ %k.2.4.1, %while.cond.4.1 ]
-  %dec.5.1 = add i32 %k.2.5.1, 1
-  br i1 false, label %while.cond.221, label %while.cond.5.1
-while.cond.221:
-  %k.2.218 = phi i32 [ %dec.220, %while.cond.221 ], [ %k.2.5.1, %while.cond.5.1 ]
-  %dec.220 = add i32 %k.2.218, 1
-  br i1 false, label %while.cond.1.2, label %while.cond.221
-while.cond.1.2:
-  %k.2.1.2 = phi i32 [ %dec.1.2, %while.cond.1.2 ], [ %k.2.218, %while.cond.221 ]
-  %dec.1.2 = add i32 %k.2.1.2, 1
-  br i1 false, label %while.cond.2.2, label %while.cond.1.2
-while.cond.2.2:
-  %k.2.2.2 = phi i32 [ %dec.2.2, %while.cond.2.2 ], [ %k.2.1.2, %while.cond.1.2 ]
-  %dec.2.2 = add i32 %k.2.2.2, 1
-  br i1 false, label %while.cond.3.2, label %while.cond.2.2
-while.cond.3.2:
-  %k.2.3.2 = phi i32 [ %dec.3.2, %while.cond.3.2 ], [ %k.2.2.2, %while.cond.2.2 ]
-  %dec.3.2 = add i32 %k.2.3.2, 1
-  br i1 false, label %while.cond.4.2, label %while.cond.3.2
-while.cond.4.2:
-  %k.2.4.2 = phi i32 [ %dec.4.2, %while.cond.4.2 ], [ %k.2.3.2, %while.cond.3.2 ]
-  %dec.4.2 = add i32 %k.2.4.2, 1
-  br i1 false, label %while.cond.5.2, label %while.cond.4.2
-while.cond.5.2:
-  %k.2.5.2 = phi i32 [ %dec.5.2, %while.cond.5.2 ], [ %k.2.4.2, %while.cond.4.2 ]
-  %dec.5.2 = add i32 %k.2.5.2, 1
-  br i1 false, label %while.cond.327, label %while.cond.5.2
-while.cond.327:
-  %k.2.324 = phi i32 [ %dec.326, %while.cond.327 ], [ %k.2.5.2, %while.cond.5.2 ]
-  %dec.326 = add i32 %k.2.324, 1
-  br i1 false, label %while.cond.1.3, label %while.cond.327
-while.cond.1.3:
-  %k.2.1.3 = phi i32 [ %dec.1.3, %while.cond.1.3 ], [ %k.2.324, %while.cond.327 ]
-  %dec.1.3 = add i32 %k.2.1.3, 1
-  br i1 false, label %while.cond.2.3, label %while.cond.1.3
-while.cond.2.3:
-  %k.2.2.3 = phi i32 [ %dec.2.3, %while.cond.2.3 ], [ %k.2.1.3, %while.cond.1.3 ]
-  %dec.2.3 = add i32 %k.2.2.3, 1
-  br i1 false, label %while.cond.3.3, label %while.cond.2.3
-while.cond.3.3:
-  %k.2.3.3 = phi i32 [ %dec.3.3, %while.cond.3.3 ], [ %k.2.2.3, %while.cond.2.3 ]
-  %dec.3.3 = add i32 %k.2.3.3, 1
-  br i1 false, label %while.cond.4.3, label %while.cond.3.3
-while.cond.4.3:
-  %k.2.4.3 = phi i32 [ %dec.4.3, %while.cond.4.3 ], [ %k.2.3.3, %while.cond.3.3 ]
-  %dec.4.3 = add i32 %k.2.4.3, 1
-  br i1 false, label %while.cond.5.3, label %while.cond.4.3
-while.cond.5.3:
-  %k.2.5.3 = phi i32 [ %dec.5.3, %while.cond.5.3 ], [ %k.2.4.3, %while.cond.4.3 ]
-  %dec.5.3 = add i32 %k.2.5.3, 1
-  br i1 false, label %while.cond.433, label %while.cond.5.3
-while.cond.433:
-  %k.2.430 = phi i32 [ %dec.432, %while.cond.433 ], [ %k.2.5.3, %while.cond.5.3 ]
-  %dec.432 = add i32 %k.2.430, 1
-  br i1 false, label %while.cond.1.4, label %while.cond.433
-while.cond.1.4:
-  %k.2.1.4 = phi i32 [ %dec.1.4, %while.cond.1.4 ], [ %k.2.430, %while.cond.433 ]
-  %dec.1.4 = add i32 %k.2.1.4, 1
-  br i1 false, label %while.cond.2.4, label %while.cond.1.4
-while.cond.2.4:
-  %k.2.2.4 = phi i32 [ %dec.2.4, %while.cond.2.4 ], [ %k.2.1.4, %while.cond.1.4 ]
-  %dec.2.4 = add i32 %k.2.2.4, 1
-  br i1 false, label %while.cond.3.4, label %while.cond.2.4
-while.cond.3.4:
-  %k.2.3.4 = phi i32 [ %dec.3.4, %while.cond.3.4 ], [ %k.2.2.4, %while.cond.2.4 ]
-  %dec.3.4 = add i32 %k.2.3.4, 1
-  br i1 false, label %while.cond.4.4, label %while.cond.3.4
-while.cond.4.4:
-  %k.2.4.4 = phi i32 [ %dec.4.4, %while.cond.4.4 ], [ %k.2.3.4, %while.cond.3.4 ]
-  %dec.4.4 = add i32 %k.2.4.4, 1
-  br i1 false, label %while.cond.5.4, label %while.cond.4.4
-while.cond.5.4:
-  %k.2.5.4 = phi i32 [ %dec.5.4, %while.cond.5.4 ], [ %k.2.4.4, %while.cond.4.4 ]
-  %dec.5.4 = add i32 %k.2.5.4, 1
-  br i1 false, label %while.cond.539, label %while.cond.5.4
-while.cond.539:
-  %k.2.536 = phi i32 [ %dec.538, %while.cond.539 ], [ %k.2.5.4, %while.cond.5.4 ]
-  %dec.538 = add i32 %k.2.536, 1
-  br i1 false, label %while.cond.1.5, label %while.cond.539
-while.cond.1.5:
-  %k.2.1.5 = phi i32 [ %dec.1.5, %while.cond.1.5 ], [ %k.2.536, %while.cond.539 ]
-  %dec.1.5 = add i32 %k.2.1.5, 1
-  br i1 false, label %while.cond.2.5, label %while.cond.1.5
-while.cond.2.5:
-  %k.2.2.5 = phi i32 [ %dec.2.5, %while.cond.2.5 ], [ %k.2.1.5, %while.cond.1.5 ]
-  %dec.2.5 = add i32 %k.2.2.5, 1
-  br i1 false, label %while.cond.3.5, label %while.cond.2.5
-while.cond.3.5:
-  %k.2.3.5 = phi i32 [ %dec.3.5, %while.cond.3.5 ], [ %k.2.2.5, %while.cond.2.5 ]
-  %dec.3.5 = add i32 %k.2.3.5, -1
-  br i1 false, label %while.cond.4.5, label %while.cond.3.5
-while.cond.4.5:
-  %k.2.4.5 = phi i32 [ %dec.4.5, %while.cond.4.5 ], [ %k.2.3.5, %while.cond.3.5 ]
-  %dec.4.5 = add i32 %k.2.4.5, -1
-  br i1 false, label %while.cond.5.5, label %while.cond.4.5
-while.cond.5.5:
-  store i32 %k.2.4.5, ptr null, align 4
-  br label %for.cond3
-}
-declare void @llvm.assume(i1 noundef)

>From ac8b385fa1e4034eba4a2c06dcf2fd47b4c69cde Mon Sep 17 00:00:00 2001
From: Le Gia Bao <legiabao7300 at gmail.com>
Date: Mon, 8 Jun 2026 11:50:59 -0400
Subject: [PATCH 4/5] format

---
 llvm/lib/Analysis/ScalarEvolution.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 38c0100855f7c..fc4009573d8f5 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -2819,9 +2819,9 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
           hasFlags(StrengthenNoWrapFlags(this, scAddExpr, {NarrowA, InnerAdd},
                                          SCEV::FlagAnyWrap),
                    SCEV::FlagNUW)) {
-        return getZeroExtendExpr(getAddExpr(NarrowA, InnerAdd, SCEV::FlagAnyWrap,
-                                            Depth + 1),
-                                 B->getType(), Depth + 1);
+        return getZeroExtendExpr(
+            getAddExpr(NarrowA, InnerAdd, SCEV::FlagAnyWrap, Depth + 1),
+            B->getType(), Depth + 1);
       }
     }
   }

>From a4e393694bfc143d94bc7c4b4e362a2c8b5bc1f0 Mon Sep 17 00:00:00 2001
From: Le Gia Bao <legiabao7300 at gmail.com>
Date: Mon, 8 Jun 2026 12:22:29 -0400
Subject: [PATCH 5/5] replace test

---
 .../ScalarEvolution/zext-add-depth-limit.ll   | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 llvm/test/Analysis/ScalarEvolution/zext-add-depth-limit.ll

diff --git a/llvm/test/Analysis/ScalarEvolution/zext-add-depth-limit.ll b/llvm/test/Analysis/ScalarEvolution/zext-add-depth-limit.ll
new file mode 100644
index 0000000000000..62480d5ec55b2
--- /dev/null
+++ b/llvm/test/Analysis/ScalarEvolution/zext-add-depth-limit.ll
@@ -0,0 +1,24 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -passes='print<scalar-evolution>' -disable-output -scalar-evolution-max-arith-depth=0 %s 2>&1 | FileCheck %s
+
+declare i32 @llvm.umax.i32(i32, i32)
+
+define i64 @zext_add_depth_limit(i32 %x) {
+; CHECK-LABEL: 'zext_add_depth_limit'
+; CHECK-NEXT:  Classifying expressions for: @zext_add_depth_limit
+; CHECK-NEXT:    %umax = call i32 @llvm.umax.i32(i32 %x, i32 5)
+; CHECK-NEXT:    --> (5 umax %x) U: [5,0) S: [5,0)
+; CHECK-NEXT:    %inner = add nuw i32 %umax, -5
+; CHECK-NEXT:    --> (-5 + (5 umax %x)) U: [0,-5) S: [0,-5)
+; CHECK-NEXT:    %z = zext i32 %inner to i64
+; CHECK-NEXT:    --> (zext i32 (-5 + (5 umax %x)) to i64) U: [0,4294967291) S: [0,4294967291)
+; CHECK-NEXT:    %sum = add i64 %z, 5
+; CHECK-NEXT:    --> (5 + (zext i32 (-5 + (5 umax %x)) to i64))<nuw><nsw> U: [5,4294967296) S: [5,4294967296)
+; CHECK-NEXT:  Determining loop execution counts for: @zext_add_depth_limit
+;
+  %umax = call i32 @llvm.umax.i32(i32 %x, i32 5)
+  %inner = add nuw i32 %umax, -5
+  %z = zext i32 %inner to i64
+  %sum = add i64 %z, 5
+  ret i64 %sum
+}



More information about the llvm-commits mailing list