[llvm] [SCEV] Add poison/undef canonicalization for SCEVAddExpr, SCEVAddRecExpr. (PR #170741)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 4 12:45:26 PST 2025


https://github.com/fhahn created https://github.com/llvm/llvm-project/pull/170741

Add poison/undef folds for SCEVAddRecExpr and SCEVAddExpr:
  * {start,+,undef/poison} -> start  - https://alive2.llvm.org/ce/z/iDbpbd
  * {undef/poison,+,step} -> undef/poison -  https://alive2.llvm.org/ce/z/Ag4AiA
  * undef/poison + x -> undef/poison - https://alive2.llvm.org/ce/z/gsNfLE

This doesn't seem to trigger in practice much, but is a follow-up to the
suggestion for https://github.com/llvm/llvm-project/commit/0e28c9bc9d64625db8e4a1707720c9eecff069a4. There may be a good reason for why we don't do
those folds currently.

Depends on https://github.com/llvm/llvm-project/pull/170740 (included in PR)

>From e32c61c9e2532d9219fa6cf3227bad8688fe1ef4 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Thu, 4 Dec 2025 17:24:58 +0000
Subject: [PATCH 1/2] [SCEV] Add m_scev_UndefOrPoison (NFC).

 with '#' will be ignored, and an empty message aborts the commit.
---
 .../llvm/Analysis/ScalarEvolutionPatternMatch.h     | 13 +++++++++++++
 llvm/lib/Analysis/LoopAccessAnalysis.cpp            |  5 ++---
 llvm/lib/Analysis/ScalarEvolution.cpp               |  7 ++-----
 3 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h b/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h
index 9354eef98fe91..f285eacc4c565 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h
@@ -380,6 +380,19 @@ m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1, const Loop_t &L) {
   return SCEVAffineAddRec_match<Op0_t, Op1_t, Loop_t>(Op0, Op1, L);
 }
 
+struct is_undef_or_poison {
+  bool match(const SCEV *S) const {
+    const SCEVUnknown *Unknown;
+    return SCEVPatternMatch::match(S, m_SCEVUnknown(Unknown)) &&
+           isa<UndefValue>(Unknown->getValue());
+  }
+};
+
+/// Match an SCEVUnknown wrapping undef or poison.
+inline is_undef_or_poison m_scev_UndefOrPoison() {
+  return is_undef_or_poison();
+}
+
 } // namespace SCEVPatternMatch
 } // namespace llvm
 
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index 5d88e5f54e3d6..df793de7c817b 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -2998,9 +2998,8 @@ void LoopAccessInfo::collectStridedAccess(Value *MemAccess) {
   if (!StrideExpr)
     return;
 
-  if (auto *Unknown = dyn_cast<SCEVUnknown>(StrideExpr))
-    if (isa<UndefValue>(Unknown->getValue()))
-      return;
+  if (match(StrideExpr, m_scev_UndefOrPoison()))
+    return;
 
   LLVM_DEBUG(dbgs() << "LAA: Found a strided access that is a candidate for "
                        "versioning:");
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 1d7a8b981b5ee..e1f90264be7a2 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -13695,11 +13695,8 @@ SCEVAddRecExpr::getPostIncExpr(ScalarEvolution &SE) const {
 
 // Return true when S contains at least an undef value.
 bool ScalarEvolution::containsUndefs(const SCEV *S) const {
-  return SCEVExprContains(S, [](const SCEV *S) {
-    if (const auto *SU = dyn_cast<SCEVUnknown>(S))
-      return isa<UndefValue>(SU->getValue());
-    return false;
-  });
+  return SCEVExprContains(
+      S, [](const SCEV *S) { return match(S, m_scev_UndefOrPoison()); });
 }
 
 // Return true when S contains a value that is a nullptr.

>From ceb58c5386dcab45975e7f8cb1badb798d27ec8d Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Thu, 4 Dec 2025 20:43:13 +0000
Subject: [PATCH 2/2] [SCEV] Add poison/undef canonicalization for SCEVAddExpr,
 SCEVAddRecExpr.

Add poison/undef folds for SCEVAddRecExpr and SCEVAddExpr:
  * {start,+,undef/poison} -> start  - https://alive2.llvm.org/ce/z/iDbpbd
  * {undef/poison,+,step} -> undef/poison -  https://alive2.llvm.org/ce/z/Ag4AiA
  * undef/poison + x -> undef/poison - https://alive2.llvm.org/ce/z/gsNfLE

This doesn't seem to trigger in practice much, but is a follow-up to the
suggestion for 0e28c9bc9. There may be a good reason for why we don't do
those folds currently.
---
 llvm/lib/Analysis/ScalarEvolution.cpp         | 14 ++++++++
 .../ScalarEvolution/different-loops-recs.ll   |  6 ++--
 .../exact-exit-count-more-precise.ll          | 14 ++++----
 .../ScalarEvolution/max-expr-cache.ll         | 36 +++++++++----------
 llvm/test/Analysis/ScalarEvolution/pr25369.ll | 12 +++----
 .../LoopVectorize/undef-inst-bug.ll           |  2 +-
 .../LoopVectorize/version-mem-access.ll       | 33 +++++------------
 7 files changed, 58 insertions(+), 59 deletions(-)

diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index e1f90264be7a2..800d5b33f86db 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -2537,6 +2537,11 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
   if (Folded)
     return Folded;
 
+  for (const SCEV *Op : Ops) {
+    if (match(Op, m_scev_UndefOrPoison()))
+      return Op;
+  }
+
   unsigned Idx = isa<SCEVConstant>(Ops[0]) ? 1 : 0;
 
   // Delay expensive flag strengthening until necessary.
@@ -3718,6 +3723,12 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
            "SCEVAddRecExpr operand is not available at loop entry!");
 #endif
 
+  // If the start is undef/poison, fold to undef/poison. Otherwise fold to the
+  // start value.
+  if (any_of(Operands,
+             [](const SCEV *Op) { return match(Op, m_scev_UndefOrPoison()); }))
+    return Operands[0];
+
   if (Operands.back()->isZero()) {
     Operands.pop_back();
     return getAddRecExpr(Operands, L, SCEV::FlagAnyWrap); // {X,+,0}  -->  X
@@ -9265,6 +9276,9 @@ ScalarEvolution::ExitLimit ScalarEvolution::computeExitLimitFromICmp(
     Pred = ICmpInst::getSwappedCmpPredicate(Pred);
   }
 
+  if (match(LHS, m_scev_UndefOrPoison()) || match(RHS, m_scev_UndefOrPoison()))
+    return getZero(LHS->getType());
+
   bool ControllingFiniteLoop = ControlsOnlyExit && loopHasNoAbnormalExits(L) &&
                                loopIsFiniteByAssumption(L);
   // Simplify the operands before analyzing them.
diff --git a/llvm/test/Analysis/ScalarEvolution/different-loops-recs.ll b/llvm/test/Analysis/ScalarEvolution/different-loops-recs.ll
index 44bff5638bc85..2ef65565cef2e 100644
--- a/llvm/test/Analysis/ScalarEvolution/different-loops-recs.ll
+++ b/llvm/test/Analysis/ScalarEvolution/different-loops-recs.ll
@@ -401,11 +401,11 @@ define void @test_04(i1 %arg) {
 ; CHECK-NEXT:    %tmp10 = sub i64 %tmp9, %tmp7
 ; CHECK-NEXT:    --> ((sext i8 %tmp8 to i64) + {-2,+,-1}<nsw><%loop2>) U: [9223372036854775682,126) S: [9223372036854775682,126) Exits: <<Unknown>> LoopDispositions: { %loop2: Variant }
 ; CHECK-NEXT:    %tmp11 = add i64 %tmp10, undef
-; CHECK-NEXT:    --> ((sext i8 %tmp8 to i64) + {(-2 + undef),+,-1}<nw><%loop2>) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop2: Variant }
+; CHECK-NEXT:    --> undef U: full-set S: full-set Exits: undef LoopDispositions: { %loop2: Invariant }
 ; CHECK-NEXT:    %tmp13 = trunc i64 %tmp11 to i32
-; CHECK-NEXT:    --> ((sext i8 %tmp8 to i32) + {(-2 + (trunc i64 undef to i32)),+,-1}<%loop2>) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop2: Variant }
+; CHECK-NEXT:    --> (trunc i64 undef to i32) U: full-set S: full-set Exits: (trunc i64 undef to i32) LoopDispositions: { %loop2: Invariant }
 ; CHECK-NEXT:    %tmp14 = sub i32 %tmp13, %tmp2
-; CHECK-NEXT:    --> ((sext i8 %tmp8 to i32) + {{\{\{}}(-4 + (trunc i64 undef to i32)),+,-1}<%loop1>,+,-1}<%loop2>) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop2: Variant }
+; CHECK-NEXT:    --> {(trunc i64 undef to i32),+,-1}<%loop1> U: full-set S: full-set Exits: {(trunc i64 undef to i32),+,-1}<%loop1> LoopDispositions: { %loop2: Invariant }
 ; CHECK-NEXT:    %tmp15 = add nuw nsw i64 %tmp7, 1
 ; CHECK-NEXT:    --> {3,+,1}<nuw><nsw><%loop2> U: [3,-9223372036854775808) S: [3,-9223372036854775808) Exits: (3 smax {2,+,1}<nuw><nsw><%loop1>) LoopDispositions: { %loop2: Computable }
 ; CHECK-NEXT:  Determining loop execution counts for: @test_04
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..cc8373aedb77e 100644
--- a/llvm/test/Analysis/ScalarEvolution/exact-exit-count-more-precise.ll
+++ b/llvm/test/Analysis/ScalarEvolution/exact-exit-count-more-precise.ll
@@ -42,19 +42,19 @@ define void @test_or() {
 ; CHECK-NEXT:    %indvars.iv = phi i64 [ -1, %BB ], [ -1, %0 ]
 ; CHECK-NEXT:    --> -1 U: [-1,0) S: [-1,0) Exits: -1 LoopDispositions: { %BB: Invariant }
 ; CHECK-NEXT:    %sum.01 = phi i32 [ %2, %BB ], [ undef, %0 ]
-; CHECK-NEXT:    --> {undef,+,-1}<%BB> U: full-set S: full-set Exits: 0 LoopDispositions: { %BB: Computable }
+; CHECK-NEXT:    --> undef U: full-set S: full-set Exits: undef LoopDispositions: { %BB: Invariant }
 ; CHECK-NEXT:    %1 = trunc i64 %indvars.iv to i32
 ; CHECK-NEXT:    --> -1 U: [-1,0) S: [-1,0) Exits: -1 LoopDispositions: { %BB: Invariant }
 ; CHECK-NEXT:    %2 = add nsw i32 %1, %sum.01
-; CHECK-NEXT:    --> {(-1 + undef),+,-1}<%BB> U: full-set S: full-set Exits: -1 LoopDispositions: { %BB: Computable }
+; CHECK-NEXT:    --> undef U: full-set S: full-set Exits: undef LoopDispositions: { %BB: Invariant }
 ; CHECK-NEXT:    %B3 = add i32 %1, %2
-; CHECK-NEXT:    --> {(-2 + undef),+,-1}<%BB> U: full-set S: full-set Exits: -2 LoopDispositions: { %BB: Computable }
+; CHECK-NEXT:    --> undef U: full-set S: full-set Exits: undef LoopDispositions: { %BB: Invariant }
 ; CHECK-NEXT:    %B = or i1 %C5, %C11
-; CHECK-NEXT:    --> (%C11 umax %C5) U: full-set S: full-set Exits: false LoopDispositions: { %BB: Variant }
+; CHECK-NEXT:    --> (%C11 umax %C5) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %BB: Variant }
 ; CHECK-NEXT:  Determining loop execution counts for: @test_or
-; CHECK-NEXT:  Loop %BB: backedge-taken count is undef
-; CHECK-NEXT:  Loop %BB: constant max backedge-taken count is i32 -1
-; CHECK-NEXT:  Loop %BB: symbolic max backedge-taken count is undef
+; CHECK-NEXT:  Loop %BB: backedge-taken count is i32 0
+; CHECK-NEXT:  Loop %BB: constant max backedge-taken count is i32 0
+; CHECK-NEXT:  Loop %BB: symbolic max backedge-taken count is i32 0
 ; CHECK-NEXT:  Loop %BB: Trip multiple is 1
 ;
   %C10 = icmp slt i1 undef, undef
diff --git a/llvm/test/Analysis/ScalarEvolution/max-expr-cache.ll b/llvm/test/Analysis/ScalarEvolution/max-expr-cache.ll
index e1c05c4b431f3..5339f3639d539 100644
--- a/llvm/test/Analysis/ScalarEvolution/max-expr-cache.ll
+++ b/llvm/test/Analysis/ScalarEvolution/max-expr-cache.ll
@@ -73,23 +73,23 @@ define void @smax(i32 %tmp3) {
 ; CHECK-NEXT:    %tmp52 = zext i32 %tmp51 to i64
 ; CHECK-NEXT:    --> (zext i32 (0 smax %tmp49) to i64) U: [0,268435456) S: [0,268435456) Exits: <<Unknown>> LoopDispositions: { %bb4: Variant, %bb53: Invariant }
 ; CHECK-NEXT:    %tmp54 = phi i64 [ undef, %bb4 ], [ %tmp59, %bb53 ]
-; CHECK-NEXT:    --> {undef,+,1}<nsw><%bb53> U: full-set S: full-set Exits: (-1 + (zext i32 (0 smax %tmp49) to i64))<nsw> LoopDispositions: { %bb53: Computable, %bb4: Variant }
+; CHECK-NEXT:    --> undef U: full-set S: full-set Exits: undef LoopDispositions: { %bb53: Invariant, %bb4: Invariant }
 ; CHECK-NEXT:    %tmp55 = trunc i64 %tmp54 to i32
-; CHECK-NEXT:    --> {(trunc i64 undef to i32),+,1}<%bb53> U: full-set S: full-set Exits: (-1 + (0 smax %tmp49))<nsw> LoopDispositions: { %bb53: Computable, %bb4: Variant }
+; CHECK-NEXT:    --> (trunc i64 undef to i32) U: full-set S: full-set Exits: (trunc i64 undef to i32) LoopDispositions: { %bb53: Invariant, %bb4: Invariant }
 ; CHECK-NEXT:    %tmp56 = shl nsw i32 %tmp55, 3
-; CHECK-NEXT:    --> {(8 * (trunc i64 undef to i32)),+,8}<%bb53> U: [0,-7) S: [-2147483648,2147483641) Exits: (-8 + (8 * (0 smax %tmp49))<nuw><nsw>)<nsw> LoopDispositions: { %bb53: Computable, %bb4: Variant }
+; CHECK-NEXT:    --> (8 * (trunc i64 undef to i32)) U: [0,-7) S: [-2147483648,2147483641) Exits: (8 * (trunc i64 undef to i32)) LoopDispositions: { %bb53: Invariant, %bb4: Invariant }
 ; CHECK-NEXT:    %tmp57 = sext i32 %tmp56 to i64
-; CHECK-NEXT:    --> (sext i32 {(8 * (trunc i64 undef to i32)),+,8}<%bb53> to i64) U: [0,-7) S: [-2147483648,2147483641) Exits: (-8 + (8 * (zext i32 (0 smax %tmp49) to i64))<nuw><nsw>)<nsw> LoopDispositions: { %bb53: Computable, %bb4: Variant }
+; CHECK-NEXT:    --> (sext i32 (8 * (trunc i64 undef to i32)) to i64) U: [0,-7) S: [-2147483648,2147483641) Exits: (sext i32 (8 * (trunc i64 undef to i32)) to i64) LoopDispositions: { %bb53: Invariant, %bb4: Invariant }
 ; CHECK-NEXT:    %tmp58 = getelementptr inbounds i8, ptr null, i64 %tmp57
-; CHECK-NEXT:    --> ((sext i32 {(8 * (trunc i64 undef to i32)),+,8}<%bb53> to i64) + null) U: [0,-7) S: [-2147483648,2147483641) Exits: (-8 + (8 * (zext i32 (0 smax %tmp49) to i64))<nuw><nsw> + null) LoopDispositions: { %bb53: Computable, %bb4: Variant }
+; CHECK-NEXT:    --> ((sext i32 (8 * (trunc i64 undef to i32)) to i64) + null) U: [0,-7) S: [-2147483648,2147483641) Exits: ((sext i32 (8 * (trunc i64 undef to i32)) to i64) + null) LoopDispositions: { %bb53: Invariant, %bb4: Invariant }
 ; CHECK-NEXT:    %tmp59 = add nsw i64 %tmp54, 1
-; CHECK-NEXT:    --> {(1 + undef),+,1}<nsw><%bb53> U: full-set S: full-set Exits: (zext i32 (0 smax %tmp49) to i64) LoopDispositions: { %bb53: Computable, %bb4: Variant }
+; CHECK-NEXT:    --> undef U: full-set S: full-set Exits: undef LoopDispositions: { %bb53: Invariant, %bb4: Invariant }
 ; CHECK-NEXT:    %tmp62 = add nuw nsw i64 %tmp5, 1
 ; CHECK-NEXT:    --> {1,+,1}<nuw><%bb4> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %bb4: Computable, %bb53: Invariant }
 ; CHECK-NEXT:  Determining loop execution counts for: @smax
-; CHECK-NEXT:  Loop %bb53: backedge-taken count is (-1 + (zext i32 (0 smax %tmp49) to i64) + (-1 * undef))
-; CHECK-NEXT:  Loop %bb53: constant max backedge-taken count is i64 -1
-; CHECK-NEXT:  Loop %bb53: symbolic max backedge-taken count is (-1 + (zext i32 (0 smax %tmp49) to i64) + (-1 * undef))
+; CHECK-NEXT:  Loop %bb53: backedge-taken count is i64 0
+; CHECK-NEXT:  Loop %bb53: constant max backedge-taken count is i64 0
+; CHECK-NEXT:  Loop %bb53: symbolic max backedge-taken count is i64 0
 ; CHECK-NEXT:  Loop %bb53: Trip multiple is 1
 ; CHECK-NEXT:  Loop %bb4: <multiple exits> Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %bb4: Unpredictable constant max backedge-taken count.
@@ -232,23 +232,23 @@ define void @umax(i32 %tmp3) {
 ; CHECK-NEXT:    %tmp52 = zext i32 %tmp51 to i64
 ; CHECK-NEXT:    --> (zext i32 %tmp49 to i64) U: [0,4294967296) S: [0,4294967296) Exits: <<Unknown>> LoopDispositions: { %bb4: Variant, %bb53: Invariant }
 ; CHECK-NEXT:    %tmp54 = phi i64 [ undef, %bb4 ], [ %tmp59, %bb53 ]
-; CHECK-NEXT:    --> {undef,+,1}<nsw><%bb53> U: full-set S: full-set Exits: (-1 + (zext i32 %tmp49 to i64))<nsw> LoopDispositions: { %bb53: Computable, %bb4: Variant }
+; CHECK-NEXT:    --> undef U: full-set S: full-set Exits: undef LoopDispositions: { %bb53: Invariant, %bb4: Invariant }
 ; CHECK-NEXT:    %tmp55 = trunc i64 %tmp54 to i32
-; CHECK-NEXT:    --> {(trunc i64 undef to i32),+,1}<%bb53> U: full-set S: full-set Exits: (-1 + %tmp49)<nsw> LoopDispositions: { %bb53: Computable, %bb4: Variant }
+; CHECK-NEXT:    --> (trunc i64 undef to i32) U: full-set S: full-set Exits: (trunc i64 undef to i32) LoopDispositions: { %bb53: Invariant, %bb4: Invariant }
 ; CHECK-NEXT:    %tmp56 = shl nsw i32 %tmp55, 3
-; CHECK-NEXT:    --> {(8 * (trunc i64 undef to i32)),+,8}<%bb53> U: [0,-7) S: [-2147483648,2147483641) Exits: (-8 + (8 * %tmp49)<nsw>) LoopDispositions: { %bb53: Computable, %bb4: Variant }
+; CHECK-NEXT:    --> (8 * (trunc i64 undef to i32)) U: [0,-7) S: [-2147483648,2147483641) Exits: (8 * (trunc i64 undef to i32)) LoopDispositions: { %bb53: Invariant, %bb4: Invariant }
 ; CHECK-NEXT:    %tmp57 = sext i32 %tmp56 to i64
-; CHECK-NEXT:    --> (sext i32 {(8 * (trunc i64 undef to i32)),+,8}<%bb53> to i64) U: [0,-7) S: [-2147483648,2147483641) Exits: (sext i32 (-8 + (8 * %tmp49)<nsw>) to i64) LoopDispositions: { %bb53: Computable, %bb4: Variant }
+; CHECK-NEXT:    --> (sext i32 (8 * (trunc i64 undef to i32)) to i64) U: [0,-7) S: [-2147483648,2147483641) Exits: (sext i32 (8 * (trunc i64 undef to i32)) to i64) LoopDispositions: { %bb53: Invariant, %bb4: Invariant }
 ; CHECK-NEXT:    %tmp58 = getelementptr inbounds i8, ptr null, i64 %tmp57
-; CHECK-NEXT:    --> ((sext i32 {(8 * (trunc i64 undef to i32)),+,8}<%bb53> to i64) + null) U: [0,-7) S: [-2147483648,2147483641) Exits: ((sext i32 (-8 + (8 * %tmp49)<nsw>) to i64) + null) LoopDispositions: { %bb53: Computable, %bb4: Variant }
+; CHECK-NEXT:    --> ((sext i32 (8 * (trunc i64 undef to i32)) to i64) + null) U: [0,-7) S: [-2147483648,2147483641) Exits: ((sext i32 (8 * (trunc i64 undef to i32)) to i64) + null) LoopDispositions: { %bb53: Invariant, %bb4: Invariant }
 ; CHECK-NEXT:    %tmp59 = add nsw i64 %tmp54, 1
-; CHECK-NEXT:    --> {(1 + undef),+,1}<nsw><%bb53> U: full-set S: full-set Exits: (zext i32 %tmp49 to i64) LoopDispositions: { %bb53: Computable, %bb4: Variant }
+; CHECK-NEXT:    --> undef U: full-set S: full-set Exits: undef LoopDispositions: { %bb53: Invariant, %bb4: Invariant }
 ; CHECK-NEXT:    %tmp62 = add nuw nsw i64 %tmp5, 1
 ; CHECK-NEXT:    --> {1,+,1}<nuw><%bb4> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %bb4: Computable, %bb53: Invariant }
 ; CHECK-NEXT:  Determining loop execution counts for: @umax
-; CHECK-NEXT:  Loop %bb53: backedge-taken count is (-1 + (zext i32 %tmp49 to i64) + (-1 * undef))
-; CHECK-NEXT:  Loop %bb53: constant max backedge-taken count is i64 -1
-; CHECK-NEXT:  Loop %bb53: symbolic max backedge-taken count is (-1 + (zext i32 %tmp49 to i64) + (-1 * undef))
+; CHECK-NEXT:  Loop %bb53: backedge-taken count is i64 0
+; CHECK-NEXT:  Loop %bb53: constant max backedge-taken count is i64 0
+; CHECK-NEXT:  Loop %bb53: symbolic max backedge-taken count is i64 0
 ; CHECK-NEXT:  Loop %bb53: Trip multiple is 1
 ; CHECK-NEXT:  Loop %bb4: <multiple exits> Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %bb4: Unpredictable constant max backedge-taken count.
diff --git a/llvm/test/Analysis/ScalarEvolution/pr25369.ll b/llvm/test/Analysis/ScalarEvolution/pr25369.ll
index e2524de3161ad..5162e3670205f 100644
--- a/llvm/test/Analysis/ScalarEvolution/pr25369.ll
+++ b/llvm/test/Analysis/ScalarEvolution/pr25369.ll
@@ -8,9 +8,9 @@ define void @hoge1(i1 %arg) {
 ;
 ; CHECK-LABEL: 'hoge1'
 ; CHECK-NEXT:  Determining loop execution counts for: @hoge1
-; CHECK-NEXT:  Loop %bb13: backedge-taken count is (-2 + (2 * undef) + %tmp7 + %tmp6)
-; CHECK-NEXT:  Loop %bb13: constant max backedge-taken count is i32 -1
-; CHECK-NEXT:  Loop %bb13: symbolic max backedge-taken count is (-2 + (2 * undef) + %tmp7 + %tmp6)
+; CHECK-NEXT:  Loop %bb13: backedge-taken count is i32 0
+; CHECK-NEXT:  Loop %bb13: constant max backedge-taken count is i32 0
+; CHECK-NEXT:  Loop %bb13: symbolic max backedge-taken count is i32 0
 ; CHECK-NEXT:  Loop %bb13: Trip multiple is 1
 ; CHECK-NEXT:  Loop %bb4: backedge-taken count is i64 20
 ; CHECK-NEXT:  Loop %bb4: constant max backedge-taken count is i64 20
@@ -57,9 +57,9 @@ define void @hoge2(i1 %arg) {
 ;
 ; CHECK-LABEL: 'hoge2'
 ; CHECK-NEXT:  Determining loop execution counts for: @hoge2
-; CHECK-NEXT:  Loop %bb13: backedge-taken count is (-2 + (2 * undef) + %tmp7 + %tmp6)
-; CHECK-NEXT:  Loop %bb13: constant max backedge-taken count is i32 -1
-; CHECK-NEXT:  Loop %bb13: symbolic max backedge-taken count is (-2 + (2 * undef) + %tmp7 + %tmp6)
+; CHECK-NEXT:  Loop %bb13: backedge-taken count is i32 0
+; CHECK-NEXT:  Loop %bb13: constant max backedge-taken count is i32 0
+; CHECK-NEXT:  Loop %bb13: symbolic max backedge-taken count is i32 0
 ; CHECK-NEXT:  Loop %bb13: Trip multiple is 1
 ; CHECK-NEXT:  Loop %bb4: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %bb4: Unpredictable constant max backedge-taken count.
diff --git a/llvm/test/Transforms/LoopVectorize/undef-inst-bug.ll b/llvm/test/Transforms/LoopVectorize/undef-inst-bug.ll
index d3cd80beaae90..5035c949e2dfd 100644
--- a/llvm/test/Transforms/LoopVectorize/undef-inst-bug.ll
+++ b/llvm/test/Transforms/LoopVectorize/undef-inst-bug.ll
@@ -28,7 +28,7 @@ for.body:
   store i32 poison, ptr %arrayidx23, align 4
   %indvars.next= add i64 %indvars.iv17, -1
   %0 = trunc i64 %indvars.next to i32
-  %cmp15 = icmp ugt i32 %0, poison
+  %cmp15 = icmp ugt i32 %0, 100
   br i1 %cmp15, label %for.body, label %loopexit
 
 loopexit:
diff --git a/llvm/test/Transforms/LoopVectorize/version-mem-access.ll b/llvm/test/Transforms/LoopVectorize/version-mem-access.ll
index 8b9a526899041..ccc08708447f0 100644
--- a/llvm/test/Transforms/LoopVectorize/version-mem-access.ll
+++ b/llvm/test/Transforms/LoopVectorize/version-mem-access.ll
@@ -128,32 +128,17 @@ exit:
 define void @stride_poison(ptr %dst) mustprogress {
 ; CHECK-LABEL: define void @stride_poison(
 ; CHECK-SAME: ptr [[DST:%.*]]) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT:  [[ENTRY:.*:]]
-; CHECK-NEXT:    [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 poison, i64 1)
-; CHECK-NEXT:    [[TMP0:%.*]] = udiv i64 99, [[UMAX]]
-; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i64 [[TMP0]], 2
-; CHECK-NEXT:    br label %[[VECTOR_PH:.*]]
-; CHECK:       [[VECTOR_PH]]:
-; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 [[TMP1]], 2
-; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 [[TMP1]], [[N_MOD_VF]]
-; CHECK-NEXT:    [[TMP2:%.*]] = mul i64 [[N_VEC]], poison
-; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]
-; CHECK:       [[VECTOR_BODY]]:
-; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
-; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], poison
-; CHECK-NEXT:    [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], poison
-; CHECK-NEXT:    [[TMP4:%.*]] = add i64 [[OFFSET_IDX]], poison
-; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DST]], i64 [[TMP3]]
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[TMP4:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr i8, ptr [[DST]], i64 [[TMP4]]
-; CHECK-NEXT:    store i8 0, ptr [[TMP5]], align 1
 ; CHECK-NEXT:    store i8 0, ptr [[TMP6]], align 1
-; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
-; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
-; CHECK-NEXT:    br i1 [[TMP7]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
-; CHECK:       [[MIDDLE_BLOCK]]:
-; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[TMP1]], [[N_VEC]]
-; CHECK-NEXT:    br i1 [[CMP_N]], [[EXIT:label %.*]], label %[[SCALAR_PH:.*]]
-; CHECK:       [[SCALAR_PH]]:
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[TMP4]], poison
+; CHECK-NEXT:    [[EC:%.*]] = icmp samesign ult i64 [[TMP4]], 100
+; CHECK-NEXT:    br i1 [[EC]], label %[[LOOP]], label %[[EXIT:.*]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    ret void
 ;
 entry:
   br label %loop



More information about the llvm-commits mailing list