[llvm] Reapply "[SCEV] Introduce loop-uniform SCEV classification." (PR #196357)

via llvm-commits llvm-commits at lists.llvm.org
Thu May 7 09:13:40 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: Ming Yan (NexMing)

<details>
<summary>Changes</summary>

This reverts commit 45d94f67b84bdc5a85aa8e3c5c266914062dcfef.

This recommit contains a small fix: when `loop-computable` are mixed with `loop-uniform`, it returns `loop-variant (unknown)`.

Original message:
This patch extends `ScalarEvolution::LoopDisposition` with a new `LoopUniform` state to describe SCEVs that are invariant across all iterations of a given loop, but may still depend on inner-loop induction variables.

Unlike `LoopInvariant`, which requires the value to be fully invariant with respect to the loop, LoopUniform captures expressions that do not depend on the loop’s own induction variables, yet may vary in nested loops. This distinction is useful for analyses and optimizations that reason about per-iteration stability at a specific loop level.

Example:
```
for (i)
  for (j)
    dep(j);       // uniform w.r.t. i
    dep(i, j);    // not uniform w.r.t. i
```

This enables us to more precisely reason about the behavior of SCEV in the context of nested loops, which is very useful for optimizations such as `LoopUnrollAndJam` and `OuterLoopVectorization`.

PR: https://github.com/llvm/llvm-project/pull/194304

---

Patch is 43.96 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/196357.diff


16 Files Affected:

- (modified) llvm/include/llvm/Analysis/ScalarEvolution.h (+24) 
- (modified) llvm/lib/Analysis/ScalarEvolution.cpp (+20-2) 
- (modified) llvm/test/Analysis/ScalarEvolution/becount-invalidation.ll (+2-2) 
- (modified) llvm/test/Analysis/ScalarEvolution/different-loops-recs.ll (+7-7) 
- (modified) llvm/test/Analysis/ScalarEvolution/exact-exit-count-more-precise.ll (+2-2) 
- (modified) llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll (+6-6) 
- (modified) llvm/test/Analysis/ScalarEvolution/flags-from-poison-noautogen.ll (+2-2) 
- (modified) llvm/test/Analysis/ScalarEvolution/incorrect-exit-count.ll (+9-9) 
- (modified) llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info-rewrite-expressions.ll (+2-2) 
- (modified) llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll (+2-2) 
- (modified) llvm/test/Analysis/ScalarEvolution/max-expr-cache.ll (+12-12) 
- (modified) llvm/test/Analysis/ScalarEvolution/outer_phi.ll (+2-2) 
- (modified) llvm/test/Analysis/ScalarEvolution/scev-dispositions.ll (+36-2) 
- (modified) llvm/test/Analysis/ScalarEvolution/trivial-phis.ll (+5-5) 
- (modified) llvm/test/Analysis/ScalarEvolution/two-loop-latches.ll (+2-2) 
- (modified) llvm/test/Analysis/ScalarEvolution/zext-add.ll (+4-4) 


``````````diff
diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index fd3a7fab1fd66..7141f7f85e374 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -630,6 +630,7 @@ class ScalarEvolution {
   enum LoopDisposition {
     LoopVariant,   ///< The SCEV is loop-variant (unknown).
     LoopInvariant, ///< The SCEV is loop-invariant.
+    LoopUniform,   ///< The SCEV is loop-uniform.
     LoopComputable ///< The SCEV varies predictably with the loop.
   };
 
@@ -1451,6 +1452,29 @@ class ScalarEvolution {
   /// loop.
   LLVM_ABI LoopDisposition getLoopDisposition(const SCEV *S, const Loop *L);
 
+  /// Returns true if the given SCEV is loop-uniform with respect to the
+  /// specified loop L.
+  ///
+  /// A SCEV is considered loop-uniform if its value is invariant across all
+  /// iterations of L, meaning it does not depend on any induction variables
+  /// or values that vary within L.
+  ///
+  /// This notion is particularly useful in nested loops, where a value may vary
+  /// in an inner loop but remain invariant in an outer loop.
+  ///
+  /// Example:
+  /// \code
+  ///   for (i)
+  ///     for (j)
+  ///       dep(j);
+  ///       dep(i, j);
+  /// \endcode
+  /// isLoopUniform(SCEV(dep(j)), loop_i) returns true, as `j` is independent of
+  /// `i`.
+  /// isLoopUniform(SCEV(dep(i, j)), loop_i) returns false, as the expression
+  /// depends on `i`, which varies in loop_i.
+  LLVM_ABI bool isLoopUniform(const SCEV *S, const Loop *L);
+
   /// Return true if the value of the given SCEV is unchanging in the
   /// specified loop.
   LLVM_ABI bool isLoopInvariant(const SCEV *S, const Loop *L);
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 94fdd36dbcb22..04f400f729b31 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -14220,6 +14220,9 @@ static raw_ostream &operator<<(raw_ostream &OS,
   case ScalarEvolution::LoopInvariant:
     OS << "Invariant";
     break;
+  case ScalarEvolution::LoopUniform:
+    OS << "Uniform";
+    break;
   case ScalarEvolution::LoopComputable:
     OS << "Computable";
     break;
@@ -14359,8 +14362,14 @@ ScalarEvolution::computeLoopDisposition(const SCEV *S, const Loop *L) {
       return LoopVariant;
 
     // Everything that is not defined at loop entry is variant.
-    if (DT.dominates(L->getHeader(), AR->getLoop()->getHeader()))
+    if (DT.dominates(L->getHeader(), AR->getLoop()->getHeader())) {
+      if (L->contains(AR->getLoop()) &&
+          llvm::all_of(AR->operands(),
+                       [&](const SCEV *Op) { return isLoopUniform(Op, L); }))
+        return LoopUniform;
+
       return LoopVariant;
+    }
     assert(!L->contains(AR->getLoop()) && "Containing loop's header does not"
            " dominate the contained loop's header?");
 
@@ -14391,14 +14400,18 @@ ScalarEvolution::computeLoopDisposition(const SCEV *S, const Loop *L) {
   case scSMinExpr:
   case scSequentialUMinExpr: {
     bool HasVarying = false;
+    bool HasUniform = false;
     for (SCEVUse Op : S->operands()) {
       LoopDisposition D = getLoopDisposition(Op, L);
       if (D == LoopVariant)
         return LoopVariant;
       if (D == LoopComputable)
         HasVarying = true;
+      if (D == LoopUniform)
+        HasUniform = true;
     }
-    return HasVarying ? LoopComputable : LoopInvariant;
+    return HasVarying ? (HasUniform ? LoopVariant : LoopComputable)
+                      : (HasUniform ? LoopUniform : LoopInvariant);
   }
   case scUnknown:
     // All non-instruction values are loop invariant.  All instructions are loop
@@ -14414,6 +14427,11 @@ ScalarEvolution::computeLoopDisposition(const SCEV *S, const Loop *L) {
   llvm_unreachable("Unknown SCEV kind!");
 }
 
+bool ScalarEvolution::isLoopUniform(const SCEV *S, const Loop *L) {
+  LoopDisposition D = getLoopDisposition(S, L);
+  return D == LoopUniform || D == LoopInvariant;
+}
+
 bool ScalarEvolution::isLoopInvariant(const SCEV *S, const Loop *L) {
   return getLoopDisposition(S, L) == LoopInvariant;
 }
diff --git a/llvm/test/Analysis/ScalarEvolution/becount-invalidation.ll b/llvm/test/Analysis/ScalarEvolution/becount-invalidation.ll
index 0e37cf5efe3e4..a0ae9b63ac02a 100644
--- a/llvm/test/Analysis/ScalarEvolution/becount-invalidation.ll
+++ b/llvm/test/Analysis/ScalarEvolution/becount-invalidation.ll
@@ -15,7 +15,7 @@ define void @test(ptr %arg) {
 ; CHECK-NEXT:    %ptr1.next = phi ptr [ %ptr2, %loop.header ], [ %ptr1.next.next, %loop2.latch ]
 ; CHECK-NEXT:    --> {%ptr2,+,8}<nuw><%loop2.header> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop2.header: Computable, %loop.header: Variant }
 ; CHECK-NEXT:    %iv = phi i64 [ 0, %loop.header ], [ %iv.next, %loop2.latch ]
-; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop2.header> U: [0,1) S: [0,1) Exits: <<Unknown>> LoopDispositions: { %loop2.header: Computable, %loop.header: Variant }
+; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop2.header> U: [0,1) S: [0,1) Exits: <<Unknown>> LoopDispositions: { %loop2.header: Computable, %loop.header: Uniform }
 ; CHECK-NEXT:    %ptr1.dummy = getelementptr inbounds i64, ptr %ptr1.next, i64 0
 ; CHECK-NEXT:    --> {%ptr2,+,8}<nuw><%loop2.header> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop2.header: Computable, %loop.header: Variant }
 ; CHECK-NEXT:    %val = load i64, ptr %ptr1.dummy, align 8
@@ -23,7 +23,7 @@ define void @test(ptr %arg) {
 ; CHECK-NEXT:    %ptr1.next.next = getelementptr inbounds i64, ptr %ptr1.next, i64 1
 ; CHECK-NEXT:    --> {(8 + %ptr2),+,8}<nw><%loop2.header> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop2.header: Computable, %loop.header: Variant }
 ; CHECK-NEXT:    %iv.next = add i64 %iv, 1
-; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop2.header> U: [1,2) S: [1,2) Exits: <<Unknown>> LoopDispositions: { %loop2.header: Computable, %loop.header: Variant }
+; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop2.header> U: [1,2) S: [1,2) Exits: <<Unknown>> LoopDispositions: { %loop2.header: Computable, %loop.header: Uniform }
 ; CHECK-NEXT:    %ptr2.next = phi ptr [ %ptr1, %if ], [ %arg, %else ]
 ; CHECK-NEXT:    --> %ptr2.next U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop.header: Variant, %loop2.header: Invariant }
 ; CHECK-NEXT:  Determining loop execution counts for: @test
diff --git a/llvm/test/Analysis/ScalarEvolution/different-loops-recs.ll b/llvm/test/Analysis/ScalarEvolution/different-loops-recs.ll
index 44bff5638bc85..9f9dd6f3c11af 100644
--- a/llvm/test/Analysis/ScalarEvolution/different-loops-recs.ll
+++ b/llvm/test/Analysis/ScalarEvolution/different-loops-recs.ll
@@ -508,9 +508,9 @@ define void @test_06() {
 ; CHECK-NEXT:    %phi1 = phi i32 [ 10, %entry ], [ %phi1.inc, %loop1.exit ]
 ; CHECK-NEXT:    --> {10,+,1}<nuw><nsw><%loop1> U: [10,1000) S: [10,1000) Exits: 999 LoopDispositions: { %loop1: Computable, %loop2: Invariant }
 ; CHECK-NEXT:    %phi2 = phi i32 [ 20, %loop1 ], [ %phi2.inc, %loop2 ]
-; CHECK-NEXT:    --> {20,+,2}<nuw><nsw><%loop2> U: [20,999) S: [20,999) Exits: 998 LoopDispositions: { %loop2: Computable, %loop1: Variant }
+; CHECK-NEXT:    --> {20,+,2}<nuw><nsw><%loop2> U: [20,999) S: [20,999) Exits: 998 LoopDispositions: { %loop2: Computable, %loop1: Uniform }
 ; CHECK-NEXT:    %phi2.inc = add i32 %phi2, 2
-; CHECK-NEXT:    --> {22,+,2}<nuw><nsw><%loop2> U: [22,1001) S: [22,1001) Exits: 1000 LoopDispositions: { %loop2: Computable, %loop1: Variant }
+; CHECK-NEXT:    --> {22,+,2}<nuw><nsw><%loop2> U: [22,1001) S: [22,1001) Exits: 1000 LoopDispositions: { %loop2: Computable, %loop1: Uniform }
 ; CHECK-NEXT:    %phi1.inc = add i32 %phi1, 1
 ; CHECK-NEXT:    --> {11,+,1}<nuw><nsw><%loop1> U: [11,1001) S: [11,1001) Exits: 1000 LoopDispositions: { %loop1: Computable, %loop2: Invariant }
 ; CHECK-NEXT:    %phi3 = phi i32 [ 30, %loop1.exit ], [ %phi3.inc, %loop3 ]
@@ -590,9 +590,9 @@ define void @test_07() {
 ; CHECK-NEXT:    %phi1 = phi i32 [ 10, %loop3 ], [ %phi1.inc, %loop1.exit ]
 ; CHECK-NEXT:    --> {10,+,1}<nuw><nsw><%loop1> U: [10,11) S: [10,11) Exits: 10 LoopDispositions: { %loop1: Computable, %loop2: Invariant }
 ; CHECK-NEXT:    %phi2 = phi i32 [ 20, %loop1 ], [ %phi2.inc, %loop2 ]
-; CHECK-NEXT:    --> {20,+,2}<nuw><nsw><%loop2> U: [20,999) S: [20,999) Exits: 998 LoopDispositions: { %loop2: Computable, %loop1: Variant }
+; CHECK-NEXT:    --> {20,+,2}<nuw><nsw><%loop2> U: [20,999) S: [20,999) Exits: 998 LoopDispositions: { %loop2: Computable, %loop1: Uniform }
 ; CHECK-NEXT:    %phi2.inc = add i32 %phi2, 2
-; CHECK-NEXT:    --> {22,+,2}<nuw><nsw><%loop2> U: [22,1001) S: [22,1001) Exits: 1000 LoopDispositions: { %loop2: Computable, %loop1: Variant }
+; CHECK-NEXT:    --> {22,+,2}<nuw><nsw><%loop2> U: [22,1001) S: [22,1001) Exits: 1000 LoopDispositions: { %loop2: Computable, %loop1: Uniform }
 ; CHECK-NEXT:    %phi1.inc = add i32 %phi1, 1
 ; CHECK-NEXT:    --> {11,+,1}<nuw><nsw><%loop1> U: [11,12) S: [11,12) Exits: 11 LoopDispositions: { %loop1: Computable, %loop2: Invariant }
 ; CHECK-NEXT:    %s1 = add i32 %phi1, %phi2
@@ -820,11 +820,11 @@ define i64 @test_10(i32 %param) {
 ; CHECK-NEXT:    %uncle = phi i64 [ %uncle.outer.next, %uncle.loop.backedge ], [ 0, %outer.loop ]
 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%uncle.loop> U: [0,1) S: [0,1) Exits: <<Unknown>> LoopDispositions: { %uncle.loop: Computable, %loop1: Invariant }
 ; CHECK-NEXT:    %iv1 = phi i64 [ %iv1.next, %guarded ], [ 0, %uncle.loop ]
-; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop1> U: [0,3) S: [0,3) Exits: 2 LoopDispositions: { %loop1: Computable, %uncle.loop: Variant }
+; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop1> U: [0,3) S: [0,3) Exits: 2 LoopDispositions: { %loop1: Computable, %uncle.loop: Uniform }
 ; CHECK-NEXT:    %iv1.trunc = trunc i64 %iv1 to i32
-; CHECK-NEXT:    --> {0,+,1}<%loop1> U: [0,3) S: [0,3) Exits: 2 LoopDispositions: { %loop1: Computable, %uncle.loop: Variant }
+; CHECK-NEXT:    --> {0,+,1}<%loop1> U: [0,3) S: [0,3) Exits: 2 LoopDispositions: { %loop1: Computable, %uncle.loop: Uniform }
 ; CHECK-NEXT:    %iv1.next = add nuw nsw i64 %iv1, 1
-; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop1> U: [1,4) S: [1,4) Exits: 3 LoopDispositions: { %loop1: Computable, %uncle.loop: Variant }
+; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop1> U: [1,4) S: [1,4) Exits: 3 LoopDispositions: { %loop1: Computable, %uncle.loop: Uniform }
 ; CHECK-NEXT:    %uncle.outer.next = add i64 %uncle, 1
 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%uncle.loop> U: [1,2) S: [1,2) Exits: <<Unknown>> LoopDispositions: { %uncle.loop: Computable, %loop1: Invariant }
 ; CHECK-NEXT:    %iv2 = phi i32 [ %iv2.next, %loop2 ], [ %param, %loop2.preheader ]
diff --git a/llvm/test/Analysis/ScalarEvolution/exact-exit-count-more-precise.ll b/llvm/test/Analysis/ScalarEvolution/exact-exit-count-more-precise.ll
index 45beb4f21e9e3..d4ed168aa4cf6 100644
--- a/llvm/test/Analysis/ScalarEvolution/exact-exit-count-more-precise.ll
+++ b/llvm/test/Analysis/ScalarEvolution/exact-exit-count-more-precise.ll
@@ -7,9 +7,9 @@ define void @test_and(i16 %in) {
 ; CHECK-LABEL: 'test_and'
 ; CHECK-NEXT:  Classifying expressions for: @test_and
 ; CHECK-NEXT:    %_tmp25.i = phi i16 [ %in, %bb2 ], [ %_tmp6.i, %bb1.i ]
-; CHECK-NEXT:    --> {%in,+,1}<nsw><%bb1.i> U: full-set S: full-set Exits: 1 LoopDispositions: { %bb1.i: Computable, %bb2: Variant }
+; CHECK-NEXT:    --> {%in,+,1}<nsw><%bb1.i> U: full-set S: full-set Exits: 1 LoopDispositions: { %bb1.i: Computable, %bb2: Uniform }
 ; CHECK-NEXT:    %_tmp6.i = add nsw i16 %_tmp25.i, 1
-; CHECK-NEXT:    --> {(1 + %in),+,1}<nsw><%bb1.i> U: full-set S: full-set Exits: 2 LoopDispositions: { %bb1.i: Computable, %bb2: Variant }
+; CHECK-NEXT:    --> {(1 + %in),+,1}<nsw><%bb1.i> U: full-set S: full-set Exits: 2 LoopDispositions: { %bb1.i: Computable, %bb2: Uniform }
 ; CHECK-NEXT:    %or.cond = and i1 %_tmp10.i, %exitcond.i
 ; CHECK-NEXT:    --> (%_tmp10.i umin %exitcond.i) U: full-set S: full-set Exits: true LoopDispositions: { %bb1.i: Variant, %bb2: Variant }
 ; CHECK-NEXT:  Determining loop execution counts for: @test_and
diff --git a/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll b/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll
index 1043b2f6f56f6..c63650aef8fe4 100644
--- a/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll
+++ b/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll
@@ -433,19 +433,19 @@ define i32 @computeSCEVAtScope(i32 %d.0) {
 ; CHECK-LABEL: 'computeSCEVAtScope'
 ; CHECK-NEXT:  Classifying expressions for: @computeSCEVAtScope
 ; CHECK-NEXT:    %d.1 = phi i32 [ %inc, %for.body ], [ %d.0, %for.cond.preheader ]
-; CHECK-NEXT:    --> {%d.0,+,1}<nsw><%for.cond> U: full-set S: full-set Exits: 0 LoopDispositions: { %for.cond: Computable, %while.cond: Variant }
+; CHECK-NEXT:    --> {%d.0,+,1}<nsw><%for.cond> U: full-set S: full-set Exits: 0 LoopDispositions: { %for.cond: Computable, %while.cond: Uniform }
 ; CHECK-NEXT:    %e.1 = phi i32 [ %inc3, %for.body ], [ %d.0, %for.cond.preheader ]
-; CHECK-NEXT:    --> {%d.0,+,1}<nsw><%for.cond> U: full-set S: full-set Exits: 0 LoopDispositions: { %for.cond: Computable, %while.cond: Variant }
+; CHECK-NEXT:    --> {%d.0,+,1}<nsw><%for.cond> U: full-set S: full-set Exits: 0 LoopDispositions: { %for.cond: Computable, %while.cond: Uniform }
 ; CHECK-NEXT:    %0 = select i1 %tobool1, i1 %tobool2, i1 false
 ; CHECK-NEXT:    --> (%tobool1 umin_seq %tobool2) U: full-set S: full-set Exits: false LoopDispositions: { %for.cond: Variant, %while.cond: Variant }
 ; CHECK-NEXT:    %inc = add nsw i32 %d.1, 1
-; CHECK-NEXT:    --> {(1 + %d.0),+,1}<nw><%for.cond> U: full-set S: full-set Exits: 1 LoopDispositions: { %for.cond: Computable, %while.cond: Variant }
+; CHECK-NEXT:    --> {(1 + %d.0),+,1}<nw><%for.cond> U: full-set S: full-set Exits: 1 LoopDispositions: { %for.cond: Computable, %while.cond: Uniform }
 ; CHECK-NEXT:    %inc3 = add nsw i32 %e.1, 1
-; CHECK-NEXT:    --> {(1 + %d.0),+,1}<nw><%for.cond> U: full-set S: full-set Exits: 1 LoopDispositions: { %for.cond: Computable, %while.cond: Variant }
+; CHECK-NEXT:    --> {(1 + %d.0),+,1}<nw><%for.cond> U: full-set S: full-set Exits: 1 LoopDispositions: { %for.cond: Computable, %while.cond: Uniform }
 ; CHECK-NEXT:    %f.1 = phi i32 [ %inc8, %for.body5 ], [ 0, %for.cond4.preheader ]
-; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%for.cond4> U: [0,1) S: [0,1) Exits: 0 LoopDispositions: { %for.cond4: Computable, %while.cond: Variant }
+; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%for.cond4> U: [0,1) S: [0,1) Exits: 0 LoopDispositions: { %for.cond4: Computable, %while.cond: Uniform }
 ; CHECK-NEXT:    %inc8 = add i32 %f.1, 1
-; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%for.cond4> U: [1,2) S: [1,2) Exits: 1 LoopDispositions: { %for.cond4: Computable, %while.cond: Variant }
+; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%for.cond4> U: [1,2) S: [1,2) Exits: 1 LoopDispositions: { %for.cond4: Computable, %while.cond: Uniform }
 ; CHECK-NEXT:  Determining loop execution counts for: @computeSCEVAtScope
 ; CHECK-NEXT:  Loop %for.cond: backedge-taken count is (-1 * %d.0)
 ; CHECK-NEXT:  Loop %for.cond: constant max backedge-taken count is i32 -1
diff --git a/llvm/test/Analysis/ScalarEvolution/flags-from-poison-noautogen.ll b/llvm/test/Analysis/ScalarEvolution/flags-from-poison-noautogen.ll
index 37ea771faf144..52843d6176a6f 100644
--- a/llvm/test/Analysis/ScalarEvolution/flags-from-poison-noautogen.ll
+++ b/llvm/test/Analysis/ScalarEvolution/flags-from-poison-noautogen.ll
@@ -15,9 +15,9 @@ define void @subrecurrences(i32 %outer_l, i32 %inner_l, i32 %val) {
 ; CHECK-NEXT:    %o_idx.inc = add nsw i32 %o_idx, 1
 ; CHECK-NEXT:    --> {1,+,1}<nuw><%outer> U: [1,0) S: [1,0) Exits: (1 + %outer_l) LoopDispositions: { %outer: Computable, %inner: Invariant }
 ; CHECK-NEXT:    %i_idx = phi i32 [ 0, %outer ], [ %i_idx.inc, %inner ]
-; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%inner> U: [0,-2147483648) S: [0,-2147483648) Exits: %inner_l LoopDispositions: { %inner: Computable, %outer: Variant }
+; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%inner> U: [0,-2147483648) S: [0,-2147483648) Exits: %inner_l LoopDispositions: { %inner: Computable, %outer: Uniform }
 ; CHECK-NEXT:    %i_idx.inc = add nsw i32 %i_idx, 1
-; CHECK-NEXT:    --> {1,+,1}<nuw><%inner> U: [1,0) S: [1,0) Exits: (1 + %inner_l) LoopDispositions: { %inner: Computable, %outer: Variant }
+; CHECK-NEXT:    --> {1,+,1}<nuw><%inner> U: [1,0) S: [1,0) Exits: (1 + %inner_l) LoopDispositions: { %inner: Computable, %outer: Uniform }
 ; CHECK-NEXT:    %v = sub nsw i32 %i_idx, %o_idx.inc
 ; CHECK-NEXT:    --> {{\{\{}}-1,+,-1}<nw><%outer>,+,1}<nsw><%inner> U: full-set S: full-set Exits: {(-1 + %inner_l),+,-1}<nw><%outer> LoopDispositions: { %inner: Computable, %outer: Variant }
 ; CHECK-NEXT:    %forub = udiv i32 1, %v
diff --git a/llvm/test/Analysis/ScalarEvolution/incorrect-exit-count.ll b/llvm/test/Analysis/ScalarEvolution/incorrect-exit-count.ll
index b456f11bade6b..f2de5e32f082e 100644
--- a/llvm/test/Analysis/ScalarEvolution/incorrect-exit-count.ll
+++ b/llvm/test/Analysis/ScalarEvolution/incorrect-exit-count.ll
@@ -17,11 +17,11 @@ define dso_local i32 @f() {
 ; CHECK-NEXT:    %storemerge23 = phi i32 [ 3, %entry ], [ %dec16, %for.inc13.3 ]
 ; CHECK-NEXT:    --> {3,+,-1}<nsw><%outer.loop> U: [1,4) S: [1,4) Exits: <<Unknown>> LoopDispositions: { %outer.loop: Computable, %for.cond6: Invariant, %inner.loop: Invariant }
 ; CHECK-NEXT:    %storemerge1921 = phi i32 [ 3, %outer.loop ], [ %dec, %for.end ]
-; CHECK-NEXT:    --> {3,+,-1}<nsw><%for.cond6> U: [3,4) S: [3,4) Exits: <<Unknown>> LoopDispositions: { %for.cond6: Computable, %outer.loop: Variant }
+; CHECK-NEXT:    --> {3,+,-1}<nsw><%for.cond6> U: [3,4) S: [3,4) Exits: <<Unknown>> LoopDispositions: { %for.cond6: Computable, %outer.loop: Uniform }
 ; CHECK-NEXT:    %idxprom20 = zext i32 %storemerge1921 to i64
-; CHECK-NEXT:    --> (zext i32 {3,+,-1}<nsw><%for.cond6> to i64) U: [3,4) S: [3,4) Exits: <<Unknown>> LoopDispositions: { %for.cond6: Computable, %outer.loop: Variant }
+; CHECK-NEXT:    --> (zext i32 {3,+,-1}<nsw><%for.cond6> to i64) U: [3,4) S: [3,4) Exits: <<Unknown>> LoopDispositions: { %for.cond6: Computable, %outer.loop: Uniform }
 ; CHECK-NEXT:    %arrayidx7 = getelementptr inbounds [1 x [4 x i16]], ptr @__const.f.g, i64 0, i64 0, i64 %idxprom20
-; CHECK-NEXT:    --> ((2 * (zext i32 {3,+,-1}<nsw><%for.cond6> to i64))<nuw><nsw> + @__const.f.g)<nuw> U: [8,-3) S: [-9223372036854775808,9223372036854775807) Exits: <<Unknown>> LoopDispositions: { %for.cond6: Computable, %outer.loop: Variant }
+; CHECK-NEXT:    --> ((2 * (zext i32 {3,+,-1}<nsw><%for.cond6> to i64))<nuw><nsw> + @__const.f.g)<nuw> U: [8,-3) S: [-9223372036854775808,9223372036854775807) Exits: <<Unknown>> LoopDispositions: { %for.cond6: Computable, %outer.loop: Uniform }
 ; CHECK-NEXT:    %i = load i16, ptr %arrayidx7, align 2
 ; CHECK-NEXT:    --> %i U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond6: Variant, %outer.loop: Variant }
 ; CHECK-NEXT:    %storemerge1822.lcssa.ph = phi i32 [ 0, %for.cond6 ]
@@ -35,25 +35,25 @@ define dso_local i32 @f() {
 ; CHECK-NEXT:    %i2 = load volatile i32, ptr @b, align 4
 ; CHECK-NEXT:    --> %i2 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond6: Variant, %outer.loop: Variant }
 ; CHECK-NEXT:    %dec = add nsw i32 %storemerge1921, -1
-; CHECK-NEXT:    --> {2,+,-1}<nsw><%for.cond6> U: [2,3) S: [2,3) Exits: <<Unknown>> LoopDispositions: { %for.cond6: Computable, %outer.loop: Variant }
+; CHECK-NEXT:    --> {2,+,-1}<nsw><%for.cond6> U: [2,3) S: [2,3) Exits: <<Unknown>> LoopDispositions: { %for.cond6: Computable, %outer.loop: Uniform }
 ; CHECK-NEXT:    %inc.lcssa.lcssa = phi i32 [ 4, %for.inc13.3 ]
 ; CHECK-NEXT:    --> 4 U: [4,5) S: [4,5)
 ; CHECK-NEXT:    %retval.0 = phi i32 [ %i1, %if.end ], [ 0, %cleanup.loopexit ]
 ; CHECK-NEXT:    --> %retval.0 U: full-set S: full-set
 ; CHECK-NEXT:    %storemerge1921.3 = phi i32 [ 3, %for.end ], [ %dec.3, %for.end.3 ]
-; CHECK-NEXT:    --> {3,+,-1}<nsw><%inner.loop> U: [3,4) S: [3,4) Exits: <<Unknown>> LoopDispositions: { %inner.loop: Computable, %outer.loop: Variant }
+; CHECK-NEXT:    --> {3,+,-1}<nsw><%inner.loop> U: [3,4) S: [3,4) Exits: <<Unknown>> LoopDispositions: { %inner.loop: Computable, %outer.loop: Uniform }
 ; CHECK-NEXT:    %idxprom20.3 = zext i32 %storemerge19...
[truncated]

``````````

</details>


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


More information about the llvm-commits mailing list