[llvm] [LoopUtils] Return 0 for estimated zero trip count loops. (PR #217330)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 24 06:52:21 PDT 2026


https://github.com/fhahn updated https://github.com/llvm/llvm-project/pull/217330

>From d40ef343e2c16cd6d9ded4c9e1dbc3436177c02a Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Wed, 19 Aug 2026 10:48:39 +0100
Subject: [PATCH 1/4] [LV, LoopUnroll] Extend tests with zero estimated trip
 counts (NFC)

Add tests for edge cases where estimated trip count is set to 0.
---
 .../LoopUnroll/zero-estimated-trip-count.ll   | 151 ++++++++++++++++++
 .../vectorize-zero-estimated-trip-count.ll    |  10 ++
 2 files changed, 161 insertions(+)
 create mode 100644 llvm/test/Transforms/LoopUnroll/zero-estimated-trip-count.ll

diff --git a/llvm/test/Transforms/LoopUnroll/zero-estimated-trip-count.ll b/llvm/test/Transforms/LoopUnroll/zero-estimated-trip-count.ll
new file mode 100644
index 0000000000000..142d1b31a8d62
--- /dev/null
+++ b/llvm/test/Transforms/LoopUnroll/zero-estimated-trip-count.ll
@@ -0,0 +1,151 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --filter "br " --filter "^.*:" --version 6
+
+; RUN: opt -passes=loop-unroll -unroll-runtime -S %s | FileCheck %s
+; RUN: opt -passes=loop-unroll -unroll-runtime -unroll-count=4 -S %s | FileCheck %s -check-prefix=FORCED
+
+; Check how loops with estimated trip counts of 0 are handled.
+
+; Test where latch weights on their own would estimate a trip count of 1024;
+; the explicit llvm.loop.estimated_trip_count of 0 takes precedence.
+define void @zero_estimated_trip_count(ptr %p, i64 %n) !prof !0 {
+; CHECK-LABEL: define void @zero_estimated_trip_count(
+; CHECK-SAME: ptr [[P:%.*]], i64 [[N:%.*]]) !prof [[PROF0:![0-9]+]] {
+; CHECK:  [[ENTRY:.*:]]
+; CHECK:    br i1 [[TMP1:%.*]], label %[[LOOP_EPIL_PREHEADER:.*]], label %[[ENTRY_NEW:.*]], !prof [[PROF1:![0-9]+]]
+; CHECK:  [[ENTRY_NEW]]:
+; CHECK:    br label %[[LOOP:.*]]
+; CHECK:  [[LOOP]]:
+; CHECK:    br i1 [[NITER_NCMP_7:%.*]], label %[[EXIT_UNR_LCSSA:.*]], label %[[LOOP]], !prof [[PROF2:![0-9]+]], !llvm.loop [[LOOP3:![0-9]+]]
+; CHECK:  [[EXIT_UNR_LCSSA]]:
+; CHECK:    br i1 [[LCMP_MOD:%.*]], label %[[LOOP_EPIL_PREHEADER]], label %[[EXIT:.*]], !prof [[PROF5:![0-9]+]]
+; CHECK:  [[LOOP_EPIL_PREHEADER]]:
+; CHECK:    br label %[[LOOP_EPIL:.*]]
+; CHECK:  [[LOOP_EPIL]]:
+; CHECK:    br i1 [[EPIL_ITER_CMP:%.*]], label %[[LOOP_EPIL]], label %[[EXIT_EPILOG_LCSSA:.*]], !prof [[PROF6:![0-9]+]], !llvm.loop [[LOOP7:![0-9]+]]
+; CHECK:  [[EXIT_EPILOG_LCSSA]]:
+; CHECK:    br label %[[EXIT]]
+; CHECK:  [[EXIT]]:
+;
+; FORCED-LABEL: define void @zero_estimated_trip_count(
+; FORCED-SAME: ptr [[P:%.*]], i64 [[N:%.*]]) !prof [[PROF0:![0-9]+]] {
+; FORCED:  [[ENTRY:.*:]]
+; FORCED:    br i1 [[TMP1:%.*]], label %[[LOOP_EPIL_PREHEADER:.*]], label %[[ENTRY_NEW:.*]], !prof [[PROF1:![0-9]+]]
+; FORCED:  [[ENTRY_NEW]]:
+; FORCED:    br label %[[LOOP:.*]]
+; FORCED:  [[LOOP]]:
+; FORCED:    br i1 [[NITER_NCMP_3:%.*]], label %[[EXIT_UNR_LCSSA:.*]], label %[[LOOP]], !prof [[PROF2:![0-9]+]], !llvm.loop [[LOOP3:![0-9]+]]
+; FORCED:  [[EXIT_UNR_LCSSA]]:
+; FORCED:    br i1 [[LCMP_MOD:%.*]], label %[[LOOP_EPIL_PREHEADER]], label %[[EXIT:.*]], !prof [[PROF6:![0-9]+]]
+; FORCED:  [[LOOP_EPIL_PREHEADER]]:
+; FORCED:    br label %[[LOOP_EPIL:.*]]
+; FORCED:  [[LOOP_EPIL]]:
+; FORCED:    br i1 [[EPIL_ITER_CMP:%.*]], label %[[LOOP_EPIL]], label %[[EXIT_EPILOG_LCSSA:.*]], !prof [[PROF7:![0-9]+]], !llvm.loop [[LOOP8:![0-9]+]]
+; FORCED:  [[EXIT_EPILOG_LCSSA]]:
+; FORCED:    br label %[[EXIT]]
+; FORCED:  [[EXIT]]:
+;
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+  %ptr = getelementptr inbounds i32, ptr %p, i64 %iv
+  %v = load i32, ptr %ptr
+  %add = add i32 %v, 1
+  store i32 %add, ptr %ptr
+  %iv.next = add i64 %iv, 1
+  %cmp.loop = icmp eq i64 %iv.next, %n
+  br i1 %cmp.loop, label %exit, label %loop, !prof !1, !llvm.loop !2
+
+exit:
+  ret void
+}
+
+; Same loop but with a high estimated trip count, which is runtime unrolled.
+define void @high_estimated_trip_count(ptr %p, i64 %n) !prof !0 {
+; CHECK-LABEL: define void @high_estimated_trip_count(
+; CHECK-SAME: ptr [[P:%.*]], i64 [[N:%.*]]) !prof [[PROF0]] {
+; CHECK:  [[ENTRY:.*:]]
+; CHECK:    br i1 [[TMP1:%.*]], label %[[LOOP_EPIL_PREHEADER:.*]], label %[[ENTRY_NEW:.*]], !prof [[PROF1]]
+; CHECK:  [[ENTRY_NEW]]:
+; CHECK:    br label %[[LOOP:.*]]
+; CHECK:  [[LOOP]]:
+; CHECK:    br i1 [[NITER_NCMP_7:%.*]], label %[[EXIT_UNR_LCSSA:.*]], label %[[LOOP]], !prof [[PROF2]], !llvm.loop [[LOOP9:![0-9]+]]
+; CHECK:  [[EXIT_UNR_LCSSA]]:
+; CHECK:    br i1 [[LCMP_MOD:%.*]], label %[[LOOP_EPIL_PREHEADER]], label %[[EXIT:.*]], !prof [[PROF5]]
+; CHECK:  [[LOOP_EPIL_PREHEADER]]:
+; CHECK:    br label %[[LOOP_EPIL:.*]]
+; CHECK:  [[LOOP_EPIL]]:
+; CHECK:    br i1 [[EPIL_ITER_CMP:%.*]], label %[[LOOP_EPIL]], label %[[EXIT_EPILOG_LCSSA:.*]], !prof [[PROF6]], !llvm.loop [[LOOP11:![0-9]+]]
+; CHECK:  [[EXIT_EPILOG_LCSSA]]:
+; CHECK:    br label %[[EXIT]]
+; CHECK:  [[EXIT]]:
+;
+; FORCED-LABEL: define void @high_estimated_trip_count(
+; FORCED-SAME: ptr [[P:%.*]], i64 [[N:%.*]]) !prof [[PROF0]] {
+; FORCED:  [[ENTRY:.*:]]
+; FORCED:    br i1 [[TMP1:%.*]], label %[[LOOP_EPIL_PREHEADER:.*]], label %[[ENTRY_NEW:.*]], !prof [[PROF1]]
+; FORCED:  [[ENTRY_NEW]]:
+; FORCED:    br label %[[LOOP:.*]]
+; FORCED:  [[LOOP]]:
+; FORCED:    br i1 [[NITER_NCMP_3:%.*]], label %[[EXIT_UNR_LCSSA:.*]], label %[[LOOP]], !prof [[PROF2]], !llvm.loop [[LOOP9:![0-9]+]]
+; FORCED:  [[EXIT_UNR_LCSSA]]:
+; FORCED:    br i1 [[LCMP_MOD:%.*]], label %[[LOOP_EPIL_PREHEADER]], label %[[EXIT:.*]], !prof [[PROF6]]
+; FORCED:  [[LOOP_EPIL_PREHEADER]]:
+; FORCED:    br label %[[LOOP_EPIL:.*]]
+; FORCED:  [[LOOP_EPIL]]:
+; FORCED:    br i1 [[EPIL_ITER_CMP:%.*]], label %[[LOOP_EPIL]], label %[[EXIT_EPILOG_LCSSA:.*]], !prof [[PROF7]], !llvm.loop [[LOOP11:![0-9]+]]
+; FORCED:  [[EXIT_EPILOG_LCSSA]]:
+; FORCED:    br label %[[EXIT]]
+; FORCED:  [[EXIT]]:
+;
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+  %ptr = getelementptr inbounds i32, ptr %p, i64 %iv
+  %v = load i32, ptr %ptr
+  %add = add i32 %v, 1
+  store i32 %add, ptr %ptr
+  %iv.next = add i64 %iv, 1
+  %cmp.loop = icmp eq i64 %iv.next, %n
+  br i1 %cmp.loop, label %exit, label %loop, !prof !1, !llvm.loop !3
+
+exit:
+  ret void
+}
+
+!0 = !{!"function_entry_count", i64 1000}
+!1 = !{!"branch_weights", i32 1, i32 1023}
+!2 = distinct !{!2, !4}
+!3 = distinct !{!3, !5}
+!4 = !{!"llvm.loop.estimated_trip_count", i32 0}
+!5 = !{!"llvm.loop.estimated_trip_count", i32 1024}
+;.
+; CHECK: [[PROF0]] = !{!"function_entry_count", i64 1000}
+; CHECK: [[PROF1]] = !{!"branch_weights", i32 14637126, i32 2132846522}
+; CHECK: [[PROF2]] = !{!"branch_weights", i32 16719984, i32 2130763664}
+; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META4:![0-9]+]]}
+; CHECK: [[META4]] = !{!"llvm.loop.estimated_trip_count", i32 0}
+; CHECK: [[PROF5]] = !{!"branch_weights", i32 1878129346, i32 269354302}
+; CHECK: [[PROF6]] = !{!"branch_weights", i32 1610087680, i32 537395968}
+; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[META8:![0-9]+]]}
+; CHECK: [[META8]] = !{!"llvm.loop.unroll.disable"}
+; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[META10:![0-9]+]]}
+; CHECK: [[META10]] = !{!"llvm.loop.estimated_trip_count", i32 128}
+; CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[META4]], [[META8]]}
+;.
+; FORCED: [[PROF0]] = !{!"function_entry_count", i64 1000}
+; FORCED: [[PROF1]] = !{!"branch_weights", i32 6285314, i32 2141198334}
+; FORCED: [[PROF2]] = !{!"branch_weights", i32 8376328, i32 2139107320}
+; FORCED: [[LOOP3]] = distinct !{[[LOOP3]], [[META4:![0-9]+]], [[META5:![0-9]+]]}
+; FORCED: [[META4]] = !{!"llvm.loop.estimated_trip_count", i32 0}
+; FORCED: [[META5]] = !{!"llvm.loop.unroll.disable"}
+; FORCED: [[PROF6]] = !{!"branch_weights", i32 1609825664, i32 537657984}
+; FORCED: [[PROF7]] = !{!"branch_weights", i32 1073392014, i32 1074091634}
+; FORCED: [[LOOP8]] = distinct !{[[LOOP8]], [[META5]]}
+; FORCED: [[LOOP9]] = distinct !{[[LOOP9]], [[META10:![0-9]+]], [[META5]]}
+; FORCED: [[META10]] = !{!"llvm.loop.estimated_trip_count", i32 256}
+; FORCED: [[LOOP11]] = distinct !{[[LOOP11]], [[META4]], [[META5]]}
+;.
diff --git a/llvm/test/Transforms/LoopVectorize/vectorize-zero-estimated-trip-count.ll b/llvm/test/Transforms/LoopVectorize/vectorize-zero-estimated-trip-count.ll
index 8cde10350bd87..1bcc04449ad16 100644
--- a/llvm/test/Transforms/LoopVectorize/vectorize-zero-estimated-trip-count.ll
+++ b/llvm/test/Transforms/LoopVectorize/vectorize-zero-estimated-trip-count.ll
@@ -5,6 +5,14 @@
 ; REQUIRES: x86-registered-target
 ; RUN: opt -passes=loop-vectorize -S %s | FileCheck %s
 
+; A zero estimated trip count means the outer loop is estimated not to be
+; entered.  It must not be used to scale the cost of the memory checks hoisted
+; out of it: that would divide by zero.  Check that the fallback trip count of 2
+; is used instead.
+; RUN: opt -passes=loop-vectorize -disable-output -debug-only=loop-vectorize %s \
+; RUN:   2>&1 | FileCheck %s -check-prefix=COST
+; REQUIRES: asserts
+
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
@@ -14,6 +22,8 @@ target triple = "x86_64-unknown-linux-gnu"
 ; CHECK: vector.body:
 ; CHECK: inner:
 
+; COST: We expect runtime memory checks to be hoisted out of the outer loop. Cost reduced from 3 to 1
+
 define void @test(ptr addrspace(1) %p, i32 %n) {
 entry:
   br label %outer

>From af4412224486ad6571a5d40d17f6f24984d562ed Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Tue, 18 Aug 2026 12:23:41 +0100
Subject: [PATCH 2/4] [LoopUtils] Return 0 for estimated zero trip count loops.

getLoopEstimatedTripCount previously returned std::nullopt for loops with
estimated tip counts of zero. This was historically due to some callers
expecting trip counts > 0.

After auditing all callers, it looks like only one call in LoopVectorize
cannot handle zero trip counts (would lead to divide by 0). Updating the
code there to explicitly check for 0 allows us to update
getEstimatedTripCount to return 0 instead of std::nullopt.

This allows us to properly preserve branch weights in the remainder
loops when vectorizing the loop, for cases where the remainder does not
execute per the estimate via updateLoopMetadataAndProfileInfo.
---
 llvm/docs/LangRef.md                          |  9 ++-
 .../include/llvm/Transforms/Utils/LoopUtils.h | 14 ++--
 llvm/lib/Transforms/Utils/LoopUtils.cpp       | 12 +--
 .../Transforms/Vectorize/LoopVectorize.cpp    |  8 +-
 .../LoopUnroll/zero-estimated-trip-count.ll   | 44 +++++------
 .../LoopVectorize/AArch64/check-prof-info.ll  | 76 +++++++++----------
 .../Transforms/Utils/LoopUtilsTest.cpp        | 14 ++--
 7 files changed, 83 insertions(+), 94 deletions(-)

diff --git a/llvm/docs/LangRef.md b/llvm/docs/LangRef.md
index e77076bb68158..ac758261c80e1 100644
--- a/llvm/docs/LangRef.md
+++ b/llvm/docs/LangRef.md
@@ -8466,10 +8466,11 @@ indicates that, each time execution reaches the peeled iterations, execution is
 estimated to exit them without reaching the remaining loop's header.
 
 Even if the probability of reaching a loop's header is low, if it is reached, it
-is the start of an iteration.  Consequently, some passes historically assume
-that `llvm::getLoopEstimatedTripCount` always returns a positive count or
-`std::nullopt`.  Thus, it returns `std::nullopt` when
-`llvm.loop.estimated_trip_count` is 0.
+is the start of an iteration.  Some passes therefore need a positive trip count.
+Even so, `llvm::getLoopEstimatedTripCount` returns 0 when
+`llvm.loop.estimated_trip_count` is 0, so that a zero estimate can be told apart
+from a missing estimate, for which it returns `std::nullopt`.  Passes that need a
+positive trip count must check for zero.
 
 #### '`llvm.licm.disable`' Metadata
 
diff --git a/llvm/include/llvm/Transforms/Utils/LoopUtils.h b/llvm/include/llvm/Transforms/Utils/LoopUtils.h
index f7c02589e9d1a..74c549be35ddf 100644
--- a/llvm/include/llvm/Transforms/Utils/LoopUtils.h
+++ b/llvm/include/llvm/Transforms/Utils/LoopUtils.h
@@ -339,15 +339,17 @@ LLVM_ABI void addStringMetadataToLoop(Loop *TheLoop, StringRef MDString);
 /// - \c std::nullopt, if the implementation is unable to handle the loop form
 ///   of \p L (e.g., \p L must have a latch block that controls the loop exit).
 /// - The value of \c llvm.loop.estimated_trip_count from the loop metadata of
-///   \p L, if that metadata is present.  In the special case that the value is
-///   zero, return \c std::nullopt instead as that is historically what callers
-///   expect when a loop is estimated to execute no iterations (i.e., its header
-///   is not reached).
+///   \p L, if that metadata is present.
 /// - Else, a new estimate of the trip count from the latch branch weights of
 ///   \p L.
 ///
-/// An estimated trip count is always a valid positive trip count, saturated at
-/// \c UINT_MAX.
+/// An estimate of zero is meaningful: it indicates that \p L is estimated not
+/// to be entered, that is, that its header is not reached.  For example, after
+/// peeling 10 or more iterations from a loop with an estimated trip count of
+/// 10, \c llvm.loop.estimated_trip_count becomes 0 on the remaining loop.
+/// Callers that need a positive trip count must check for zero.
+///
+/// An estimated trip count is saturated at \c UINT_MAX.
 ///
 /// In addition, if \p EstimatedLoopInvocationWeight, then either:
 /// - Set \c *EstimatedLoopInvocationWeight to the weight of the latch's branch
diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp
index 8ec435f6e3174..cf200126f447d 100644
--- a/llvm/lib/Transforms/Utils/LoopUtils.cpp
+++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp
@@ -956,20 +956,12 @@ llvm::getLoopEstimatedTripCount(Loop *L,
   // indicates that, each time execution reaches the peeled iterations,
   // execution is estimated to exit them without reaching the remaining loop's
   // header.
-  //
-  // Even if the probability of reaching a loop's header is low, if it is
-  // reached, it is the start of an iteration.  Consequently, some passes
-  // historically assume that llvm::getLoopEstimatedTripCount always returns a
-  // positive count or std::nullopt.  Thus, return std::nullopt when
-  // llvm.loop.estimated_trip_count is 0.
   if (std::optional<unsigned> TC =
           getOptionalIntLoopAttribute(L, LLVMLoopEstimatedTripCount)) {
     LLVM_DEBUG(dbgs() << "getLoopEstimatedTripCount: "
                       << LLVMLoopEstimatedTripCount << " metadata has trip "
-                      << "count of " << *TC
-                      << (*TC == 0 ? " (returning std::nullopt)" : "")
-                      << " for " << DbgLoop(L) << "\n");
-    return *TC == 0 ? std::nullopt : TC;
+                      << "count of " << *TC << " for " << DbgLoop(L) << "\n");
+    return TC;
   }
 
   // Estimate the trip count from latch branch weights.
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 5e8a43eb871c5..a5bf08c1893d8 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -486,9 +486,13 @@ static std::optional<ElementCount> getSmallBestKnownTC(
     return ExpectedTC;
 
   // Check if there is an expected trip count available from profile data.
+  // An estimate of zero means the loop is estimated not to be entered; it is
+  // not a usable trip count for the profitability decisions below (and would
+  // e.g. divide by zero when scaling runtime check cost), so treat it as
+  // unknown.
   if (LoopVectorizeWithBlockFrequency && !ComputeUpperBoundOnly)
-    if (auto EstimatedTC = getLoopEstimatedTripCount(L))
-      return ElementCount::getFixed(*EstimatedTC);
+    if (unsigned EstimatedTC = getLoopEstimatedTripCount(L).value_or(0))
+      return ElementCount::getFixed(EstimatedTC);
 
   if (!CanUseConstantMax)
     return std::nullopt;
diff --git a/llvm/test/Transforms/LoopUnroll/zero-estimated-trip-count.ll b/llvm/test/Transforms/LoopUnroll/zero-estimated-trip-count.ll
index 142d1b31a8d62..17403f4f76897 100644
--- a/llvm/test/Transforms/LoopUnroll/zero-estimated-trip-count.ll
+++ b/llvm/test/Transforms/LoopUnroll/zero-estimated-trip-count.ll
@@ -11,19 +11,9 @@ define void @zero_estimated_trip_count(ptr %p, i64 %n) !prof !0 {
 ; CHECK-LABEL: define void @zero_estimated_trip_count(
 ; CHECK-SAME: ptr [[P:%.*]], i64 [[N:%.*]]) !prof [[PROF0:![0-9]+]] {
 ; CHECK:  [[ENTRY:.*:]]
-; CHECK:    br i1 [[TMP1:%.*]], label %[[LOOP_EPIL_PREHEADER:.*]], label %[[ENTRY_NEW:.*]], !prof [[PROF1:![0-9]+]]
-; CHECK:  [[ENTRY_NEW]]:
 ; CHECK:    br label %[[LOOP:.*]]
 ; CHECK:  [[LOOP]]:
-; CHECK:    br i1 [[NITER_NCMP_7:%.*]], label %[[EXIT_UNR_LCSSA:.*]], label %[[LOOP]], !prof [[PROF2:![0-9]+]], !llvm.loop [[LOOP3:![0-9]+]]
-; CHECK:  [[EXIT_UNR_LCSSA]]:
-; CHECK:    br i1 [[LCMP_MOD:%.*]], label %[[LOOP_EPIL_PREHEADER]], label %[[EXIT:.*]], !prof [[PROF5:![0-9]+]]
-; CHECK:  [[LOOP_EPIL_PREHEADER]]:
-; CHECK:    br label %[[LOOP_EPIL:.*]]
-; CHECK:  [[LOOP_EPIL]]:
-; CHECK:    br i1 [[EPIL_ITER_CMP:%.*]], label %[[LOOP_EPIL]], label %[[EXIT_EPILOG_LCSSA:.*]], !prof [[PROF6:![0-9]+]], !llvm.loop [[LOOP7:![0-9]+]]
-; CHECK:  [[EXIT_EPILOG_LCSSA]]:
-; CHECK:    br label %[[EXIT]]
+; CHECK:    br i1 [[CMP_LOOP:%.*]], label %[[EXIT:.*]], label %[[LOOP]], !prof [[PROF1:![0-9]+]], !llvm.loop [[LOOP2:![0-9]+]]
 ; CHECK:  [[EXIT]]:
 ;
 ; FORCED-LABEL: define void @zero_estimated_trip_count(
@@ -66,17 +56,17 @@ define void @high_estimated_trip_count(ptr %p, i64 %n) !prof !0 {
 ; CHECK-LABEL: define void @high_estimated_trip_count(
 ; CHECK-SAME: ptr [[P:%.*]], i64 [[N:%.*]]) !prof [[PROF0]] {
 ; CHECK:  [[ENTRY:.*:]]
-; CHECK:    br i1 [[TMP1:%.*]], label %[[LOOP_EPIL_PREHEADER:.*]], label %[[ENTRY_NEW:.*]], !prof [[PROF1]]
+; CHECK:    br i1 [[TMP1:%.*]], label %[[LOOP_EPIL_PREHEADER:.*]], label %[[ENTRY_NEW:.*]], !prof [[PROF4:![0-9]+]]
 ; CHECK:  [[ENTRY_NEW]]:
 ; CHECK:    br label %[[LOOP:.*]]
 ; CHECK:  [[LOOP]]:
-; CHECK:    br i1 [[NITER_NCMP_7:%.*]], label %[[EXIT_UNR_LCSSA:.*]], label %[[LOOP]], !prof [[PROF2]], !llvm.loop [[LOOP9:![0-9]+]]
+; CHECK:    br i1 [[NITER_NCMP_7:%.*]], label %[[EXIT_UNR_LCSSA:.*]], label %[[LOOP]], !prof [[PROF5:![0-9]+]], !llvm.loop [[LOOP6:![0-9]+]]
 ; CHECK:  [[EXIT_UNR_LCSSA]]:
-; CHECK:    br i1 [[LCMP_MOD:%.*]], label %[[LOOP_EPIL_PREHEADER]], label %[[EXIT:.*]], !prof [[PROF5]]
+; CHECK:    br i1 [[LCMP_MOD:%.*]], label %[[LOOP_EPIL_PREHEADER]], label %[[EXIT:.*]], !prof [[PROF8:![0-9]+]]
 ; CHECK:  [[LOOP_EPIL_PREHEADER]]:
 ; CHECK:    br label %[[LOOP_EPIL:.*]]
 ; CHECK:  [[LOOP_EPIL]]:
-; CHECK:    br i1 [[EPIL_ITER_CMP:%.*]], label %[[LOOP_EPIL]], label %[[EXIT_EPILOG_LCSSA:.*]], !prof [[PROF6]], !llvm.loop [[LOOP11:![0-9]+]]
+; CHECK:    br i1 [[EPIL_ITER_CMP:%.*]], label %[[LOOP_EPIL]], label %[[EXIT_EPILOG_LCSSA:.*]], !prof [[PROF9:![0-9]+]], !llvm.loop [[LOOP10:![0-9]+]]
 ; CHECK:  [[EXIT_EPILOG_LCSSA]]:
 ; CHECK:    br label %[[EXIT]]
 ; CHECK:  [[EXIT]]:
@@ -124,17 +114,17 @@ exit:
 !5 = !{!"llvm.loop.estimated_trip_count", i32 1024}
 ;.
 ; CHECK: [[PROF0]] = !{!"function_entry_count", i64 1000}
-; CHECK: [[PROF1]] = !{!"branch_weights", i32 14637126, i32 2132846522}
-; CHECK: [[PROF2]] = !{!"branch_weights", i32 16719984, i32 2130763664}
-; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META4:![0-9]+]]}
-; CHECK: [[META4]] = !{!"llvm.loop.estimated_trip_count", i32 0}
-; CHECK: [[PROF5]] = !{!"branch_weights", i32 1878129346, i32 269354302}
-; CHECK: [[PROF6]] = !{!"branch_weights", i32 1610087680, i32 537395968}
-; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[META8:![0-9]+]]}
-; CHECK: [[META8]] = !{!"llvm.loop.unroll.disable"}
-; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[META10:![0-9]+]]}
-; CHECK: [[META10]] = !{!"llvm.loop.estimated_trip_count", i32 128}
-; CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[META4]], [[META8]]}
+; CHECK: [[PROF1]] = !{!"branch_weights", i32 1, i32 1023}
+; CHECK: [[LOOP2]] = distinct !{[[LOOP2]], [[META3:![0-9]+]]}
+; CHECK: [[META3]] = !{!"llvm.loop.estimated_trip_count", i32 0}
+; CHECK: [[PROF4]] = !{!"branch_weights", i32 14637126, i32 2132846522}
+; CHECK: [[PROF5]] = !{!"branch_weights", i32 16719984, i32 2130763664}
+; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[META7:![0-9]+]]}
+; CHECK: [[META7]] = !{!"llvm.loop.estimated_trip_count", i32 128}
+; CHECK: [[PROF8]] = !{!"branch_weights", i32 1878129346, i32 269354302}
+; CHECK: [[PROF9]] = !{!"branch_weights", i32 1610087680, i32 537395968}
+; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META3]], [[META11:![0-9]+]]}
+; CHECK: [[META11]] = !{!"llvm.loop.unroll.disable"}
 ;.
 ; FORCED: [[PROF0]] = !{!"function_entry_count", i64 1000}
 ; FORCED: [[PROF1]] = !{!"branch_weights", i32 6285314, i32 2141198334}
@@ -144,7 +134,7 @@ exit:
 ; FORCED: [[META5]] = !{!"llvm.loop.unroll.disable"}
 ; FORCED: [[PROF6]] = !{!"branch_weights", i32 1609825664, i32 537657984}
 ; FORCED: [[PROF7]] = !{!"branch_weights", i32 1073392014, i32 1074091634}
-; FORCED: [[LOOP8]] = distinct !{[[LOOP8]], [[META5]]}
+; FORCED: [[LOOP8]] = distinct !{[[LOOP8]], [[META4]], [[META5]]}
 ; FORCED: [[LOOP9]] = distinct !{[[LOOP9]], [[META10:![0-9]+]], [[META5]]}
 ; FORCED: [[META10]] = !{!"llvm.loop.estimated_trip_count", i32 256}
 ; FORCED: [[LOOP11]] = distinct !{[[LOOP11]], [[META4]], [[META5]]}
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/check-prof-info.ll b/llvm/test/Transforms/LoopVectorize/AArch64/check-prof-info.ll
index 106d046a8e2d6..06b6a2625b1a9 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/check-prof-info.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/check-prof-info.ll
@@ -46,13 +46,13 @@ define void @foo_i32(i64 %n) {
 ; CHECK-V1-IC1-FORCE-EPI2:  [[VEC_EPILOG_PH]]:
 ; CHECK-V1-IC1-FORCE-EPI2:    br label %[[VEC_EPILOG_VECTOR_BODY:.*]]
 ; CHECK-V1-IC1-FORCE-EPI2:  [[VEC_EPILOG_VECTOR_BODY]]:
-; CHECK-V1-IC1-FORCE-EPI2:    br i1 [[TMP8:%.*]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP7:![0-9]+]]
+; CHECK-V1-IC1-FORCE-EPI2:    br i1 [[TMP9:%.*]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !prof [[PROF7:![0-9]+]], !llvm.loop [[LOOP8:![0-9]+]]
 ; CHECK-V1-IC1-FORCE-EPI2:  [[VEC_EPILOG_MIDDLE_BLOCK]]:
-; CHECK-V1-IC1-FORCE-EPI2:    br i1 [[CMP_N7:%.*]], label %[[FOR_COND_CLEANUP]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF9:![0-9]+]]
+; CHECK-V1-IC1-FORCE-EPI2:    br i1 [[CMP_N6:%.*]], label %[[FOR_COND_CLEANUP]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF10:![0-9]+]]
 ; CHECK-V1-IC1-FORCE-EPI2:  [[VEC_EPILOG_SCALAR_PH]]:
 ; CHECK-V1-IC1-FORCE-EPI2:    br label %[[FOR_BODY:.*]]
 ; CHECK-V1-IC1-FORCE-EPI2:  [[FOR_BODY]]:
-; CHECK-V1-IC1-FORCE-EPI2:    br i1 [[EXITCOND:%.*]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]], !prof [[PROF10:![0-9]+]], !llvm.loop [[LOOP11:![0-9]+]]
+; CHECK-V1-IC1-FORCE-EPI2:    br i1 [[EXITCOND:%.*]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]], !prof [[PROF7]], !llvm.loop [[LOOP11:![0-9]+]]
 ; CHECK-V1-IC1-FORCE-EPI2:  [[FOR_COND_CLEANUP]]:
 ;
 ; CHECK-V2-IC1-LABEL: define void @foo_i32(
@@ -62,7 +62,7 @@ define void @foo_i32(i64 %n) {
 ; CHECK-V2-IC1:  [[VECTOR_PH]]:
 ; CHECK-V2-IC1:    br label %[[VECTOR_BODY:.*]]
 ; CHECK-V2-IC1:  [[VECTOR_BODY]]:
-; CHECK-V2-IC1:    br i1 [[TMP2:%.*]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !prof [[PROF1:![0-9]+]], !llvm.loop [[LOOP2:![0-9]+]]
+; CHECK-V2-IC1:    br i1 [[TMP3:%.*]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !prof [[PROF1:![0-9]+]], !llvm.loop [[LOOP2:![0-9]+]]
 ; CHECK-V2-IC1:  [[MIDDLE_BLOCK]]:
 ; CHECK-V2-IC1:    br i1 [[CMP_N:%.*]], label %[[FOR_COND_CLEANUP:.*]], label %[[SCALAR_PH]], !prof [[PROF6:![0-9]+]]
 ; CHECK-V2-IC1:  [[SCALAR_PH]]:
@@ -80,7 +80,7 @@ define void @foo_i32(i64 %n) {
 ; CHECK-V2-IC4:  [[VECTOR_PH]]:
 ; CHECK-V2-IC4:    br label %[[VECTOR_BODY:.*]]
 ; CHECK-V2-IC4:  [[VECTOR_BODY]]:
-; CHECK-V2-IC4:    br i1 [[TMP8:%.*]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !prof [[PROF1:![0-9]+]], !llvm.loop [[LOOP2:![0-9]+]]
+; CHECK-V2-IC4:    br i1 [[TMP9:%.*]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !prof [[PROF1:![0-9]+]], !llvm.loop [[LOOP2:![0-9]+]]
 ; CHECK-V2-IC4:  [[MIDDLE_BLOCK]]:
 ; CHECK-V2-IC4:    br i1 [[CMP_N:%.*]], label %[[FOR_COND_CLEANUP:.*]], label %[[VEC_EPILOG_ITER_CHECK:.*]], !prof [[PROF6:![0-9]+]]
 ; CHECK-V2-IC4:  [[VEC_EPILOG_ITER_CHECK]]:
@@ -88,13 +88,13 @@ define void @foo_i32(i64 %n) {
 ; CHECK-V2-IC4:  [[VEC_EPILOG_PH]]:
 ; CHECK-V2-IC4:    br label %[[VEC_EPILOG_VECTOR_BODY:.*]]
 ; CHECK-V2-IC4:  [[VEC_EPILOG_VECTOR_BODY]]:
-; CHECK-V2-IC4:    br i1 [[TMP11:%.*]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
+; CHECK-V2-IC4:    br i1 [[TMP13:%.*]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !prof [[PROF8:![0-9]+]], !llvm.loop [[LOOP9:![0-9]+]]
 ; CHECK-V2-IC4:  [[VEC_EPILOG_MIDDLE_BLOCK]]:
-; CHECK-V2-IC4:    br i1 [[CMP_N10:%.*]], label %[[FOR_COND_CLEANUP]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF10:![0-9]+]]
+; CHECK-V2-IC4:    br i1 [[CMP_N9:%.*]], label %[[FOR_COND_CLEANUP]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF11:![0-9]+]]
 ; CHECK-V2-IC4:  [[VEC_EPILOG_SCALAR_PH]]:
 ; CHECK-V2-IC4:    br label %[[FOR_BODY:.*]]
 ; CHECK-V2-IC4:  [[FOR_BODY]]:
-; CHECK-V2-IC4:    br i1 [[EXITCOND:%.*]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]], !prof [[PROF11:![0-9]+]], !llvm.loop [[LOOP12:![0-9]+]]
+; CHECK-V2-IC4:    br i1 [[EXITCOND:%.*]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]], !prof [[PROF8]], !llvm.loop [[LOOP12:![0-9]+]]
 ; CHECK-V2-IC4:  [[FOR_COND_CLEANUP]]:
 ;
 entry:
@@ -132,9 +132,9 @@ define void @foo_i8(i64 %n) {
 ; CHECK-V1-IC1:  [[VEC_EPILOG_PH]]:
 ; CHECK-V1-IC1:    br label %[[VEC_EPILOG_VECTOR_BODY:.*]]
 ; CHECK-V1-IC1:  [[VEC_EPILOG_VECTOR_BODY]]:
-; CHECK-V1-IC1:    br i1 [[TMP8:%.*]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP13:![0-9]+]]
+; CHECK-V1-IC1:    br i1 [[TMP9:%.*]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !prof [[PROF6]], !llvm.loop [[LOOP13:![0-9]+]]
 ; CHECK-V1-IC1:  [[VEC_EPILOG_MIDDLE_BLOCK]]:
-; CHECK-V1-IC1:    br i1 [[CMP_N7:%.*]], label %[[FOR_COND_CLEANUP]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF14:![0-9]+]]
+; CHECK-V1-IC1:    br i1 [[CMP_N6:%.*]], label %[[FOR_COND_CLEANUP]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF14:![0-9]+]]
 ; CHECK-V1-IC1:  [[VEC_EPILOG_SCALAR_PH]]:
 ; CHECK-V1-IC1:    br label %[[FOR_BODY:.*]]
 ; CHECK-V1-IC1:  [[FOR_BODY]]:
@@ -158,13 +158,13 @@ define void @foo_i8(i64 %n) {
 ; CHECK-V1-IC1-FORCE-EPI2:  [[VEC_EPILOG_PH]]:
 ; CHECK-V1-IC1-FORCE-EPI2:    br label %[[VEC_EPILOG_VECTOR_BODY:.*]]
 ; CHECK-V1-IC1-FORCE-EPI2:  [[VEC_EPILOG_VECTOR_BODY]]:
-; CHECK-V1-IC1-FORCE-EPI2:    br i1 [[TMP8:%.*]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]]
+; CHECK-V1-IC1-FORCE-EPI2:    br i1 [[TMP9:%.*]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !prof [[PROF7]], !llvm.loop [[LOOP16:![0-9]+]]
 ; CHECK-V1-IC1-FORCE-EPI2:  [[VEC_EPILOG_MIDDLE_BLOCK]]:
-; CHECK-V1-IC1-FORCE-EPI2:    br i1 [[CMP_N7:%.*]], label %[[FOR_COND_CLEANUP]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF9]]
+; CHECK-V1-IC1-FORCE-EPI2:    br i1 [[CMP_N6:%.*]], label %[[FOR_COND_CLEANUP]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF10]]
 ; CHECK-V1-IC1-FORCE-EPI2:  [[VEC_EPILOG_SCALAR_PH]]:
 ; CHECK-V1-IC1-FORCE-EPI2:    br label %[[FOR_BODY:.*]]
 ; CHECK-V1-IC1-FORCE-EPI2:  [[FOR_BODY]]:
-; CHECK-V1-IC1-FORCE-EPI2:    br i1 [[EXITCOND:%.*]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]], !prof [[PROF10]], !llvm.loop [[LOOP17:![0-9]+]]
+; CHECK-V1-IC1-FORCE-EPI2:    br i1 [[EXITCOND:%.*]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]], !prof [[PROF7]], !llvm.loop [[LOOP17:![0-9]+]]
 ; CHECK-V1-IC1-FORCE-EPI2:  [[FOR_COND_CLEANUP]]:
 ;
 ; CHECK-V2-IC1-LABEL: define void @foo_i8(
@@ -176,7 +176,7 @@ define void @foo_i8(i64 %n) {
 ; CHECK-V2-IC1:  [[VECTOR_PH]]:
 ; CHECK-V2-IC1:    br label %[[VECTOR_BODY:.*]]
 ; CHECK-V2-IC1:  [[VECTOR_BODY]]:
-; CHECK-V2-IC1:    br i1 [[TMP6:%.*]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !prof [[PROF10:![0-9]+]], !llvm.loop [[LOOP11:![0-9]+]]
+; CHECK-V2-IC1:    br i1 [[TMP3:%.*]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !prof [[PROF10:![0-9]+]], !llvm.loop [[LOOP11:![0-9]+]]
 ; CHECK-V2-IC1:  [[MIDDLE_BLOCK]]:
 ; CHECK-V2-IC1:    br i1 [[CMP_N:%.*]], label %[[FOR_COND_CLEANUP:.*]], label %[[VEC_EPILOG_ITER_CHECK:.*]], !prof [[PROF13:![0-9]+]]
 ; CHECK-V2-IC1:  [[VEC_EPILOG_ITER_CHECK]]:
@@ -184,9 +184,9 @@ define void @foo_i8(i64 %n) {
 ; CHECK-V2-IC1:  [[VEC_EPILOG_PH]]:
 ; CHECK-V2-IC1:    br label %[[VEC_EPILOG_VECTOR_BODY:.*]]
 ; CHECK-V2-IC1:  [[VEC_EPILOG_VECTOR_BODY]]:
-; CHECK-V2-IC1:    br i1 [[TMP11:%.*]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP15:![0-9]+]]
+; CHECK-V2-IC1:    br i1 [[TMP7:%.*]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !prof [[PROF7]], !llvm.loop [[LOOP15:![0-9]+]]
 ; CHECK-V2-IC1:  [[VEC_EPILOG_MIDDLE_BLOCK]]:
-; CHECK-V2-IC1:    br i1 [[CMP_N7:%.*]], label %[[FOR_COND_CLEANUP]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF6]]
+; CHECK-V2-IC1:    br i1 [[CMP_N6:%.*]], label %[[FOR_COND_CLEANUP]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF6]]
 ; CHECK-V2-IC1:  [[VEC_EPILOG_SCALAR_PH]]:
 ; CHECK-V2-IC1:    br label %[[FOR_BODY:.*]]
 ; CHECK-V2-IC1:  [[FOR_BODY]]:
@@ -202,7 +202,7 @@ define void @foo_i8(i64 %n) {
 ; CHECK-V2-IC4:  [[VECTOR_PH]]:
 ; CHECK-V2-IC4:    br label %[[VECTOR_BODY:.*]]
 ; CHECK-V2-IC4:  [[VECTOR_BODY]]:
-; CHECK-V2-IC4:    br i1 [[TMP8:%.*]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !prof [[PROF6]], !llvm.loop [[LOOP13:![0-9]+]]
+; CHECK-V2-IC4:    br i1 [[TMP9:%.*]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !prof [[PROF6]], !llvm.loop [[LOOP13:![0-9]+]]
 ; CHECK-V2-IC4:  [[MIDDLE_BLOCK]]:
 ; CHECK-V2-IC4:    br i1 [[CMP_N:%.*]], label %[[FOR_COND_CLEANUP:.*]], label %[[VEC_EPILOG_ITER_CHECK:.*]], !prof [[PROF1]]
 ; CHECK-V2-IC4:  [[VEC_EPILOG_ITER_CHECK]]:
@@ -210,13 +210,13 @@ define void @foo_i8(i64 %n) {
 ; CHECK-V2-IC4:  [[VEC_EPILOG_PH]]:
 ; CHECK-V2-IC4:    br label %[[VEC_EPILOG_VECTOR_BODY:.*]]
 ; CHECK-V2-IC4:  [[VEC_EPILOG_VECTOR_BODY]]:
-; CHECK-V2-IC4:    br i1 [[TMP11:%.*]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]]
+; CHECK-V2-IC4:    br i1 [[TMP13:%.*]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !prof [[PROF8]], !llvm.loop [[LOOP16:![0-9]+]]
 ; CHECK-V2-IC4:  [[VEC_EPILOG_MIDDLE_BLOCK]]:
-; CHECK-V2-IC4:    br i1 [[CMP_N10:%.*]], label %[[FOR_COND_CLEANUP]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF17:![0-9]+]]
+; CHECK-V2-IC4:    br i1 [[CMP_N9:%.*]], label %[[FOR_COND_CLEANUP]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF17:![0-9]+]]
 ; CHECK-V2-IC4:  [[VEC_EPILOG_SCALAR_PH]]:
 ; CHECK-V2-IC4:    br label %[[FOR_BODY:.*]]
 ; CHECK-V2-IC4:  [[FOR_BODY]]:
-; CHECK-V2-IC4:    br i1 [[EXITCOND:%.*]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]], !prof [[PROF11]], !llvm.loop [[LOOP18:![0-9]+]]
+; CHECK-V2-IC4:    br i1 [[EXITCOND:%.*]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]], !prof [[PROF8]], !llvm.loop [[LOOP18:![0-9]+]]
 ; CHECK-V2-IC4:  [[FOR_COND_CLEANUP]]:
 ;
 entry:
@@ -270,7 +270,7 @@ define void @foo_i32_no_bw(i64 %n) {
 ; CHECK-V1-IC1-FORCE-EPI2:  [[VEC_EPILOG_PH]]:
 ; CHECK-V1-IC1-FORCE-EPI2:    br label %[[VEC_EPILOG_VECTOR_BODY:.*]]
 ; CHECK-V1-IC1-FORCE-EPI2:  [[VEC_EPILOG_VECTOR_BODY]]:
-; CHECK-V1-IC1-FORCE-EPI2:    br i1 [[TMP8:%.*]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP19:![0-9]+]]
+; CHECK-V1-IC1-FORCE-EPI2:    br i1 [[TMP9:%.*]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP19:![0-9]+]]
 ; CHECK-V1-IC1-FORCE-EPI2:  [[VEC_EPILOG_MIDDLE_BLOCK]]:
 ; CHECK-V1-IC1-FORCE-EPI2:    br i1 [[CMP_N7:%.*]], label %[[FOR_COND_CLEANUP]], label %[[VEC_EPILOG_SCALAR_PH]]
 ; CHECK-V1-IC1-FORCE-EPI2:  [[VEC_EPILOG_SCALAR_PH]]:
@@ -286,7 +286,7 @@ define void @foo_i32_no_bw(i64 %n) {
 ; CHECK-V2-IC1:  [[VECTOR_PH]]:
 ; CHECK-V2-IC1:    br label %[[VECTOR_BODY:.*]]
 ; CHECK-V2-IC1:  [[VECTOR_BODY]]:
-; CHECK-V2-IC1:    br i1 [[TMP2:%.*]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP17:![0-9]+]]
+; CHECK-V2-IC1:    br i1 [[TMP3:%.*]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP17:![0-9]+]]
 ; CHECK-V2-IC1:  [[MIDDLE_BLOCK]]:
 ; CHECK-V2-IC1:    br i1 [[CMP_N:%.*]], label %[[FOR_COND_CLEANUP:.*]], label %[[SCALAR_PH]]
 ; CHECK-V2-IC1:  [[SCALAR_PH]]:
@@ -304,7 +304,7 @@ define void @foo_i32_no_bw(i64 %n) {
 ; CHECK-V2-IC4:  [[VECTOR_PH]]:
 ; CHECK-V2-IC4:    br label %[[VECTOR_BODY:.*]]
 ; CHECK-V2-IC4:  [[VECTOR_BODY]]:
-; CHECK-V2-IC4:    br i1 [[TMP8:%.*]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP19:![0-9]+]]
+; CHECK-V2-IC4:    br i1 [[TMP9:%.*]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP19:![0-9]+]]
 ; CHECK-V2-IC4:  [[MIDDLE_BLOCK]]:
 ; CHECK-V2-IC4:    br i1 [[CMP_N:%.*]], label %[[FOR_COND_CLEANUP:.*]], label %[[VEC_EPILOG_ITER_CHECK:.*]]
 ; CHECK-V2-IC4:  [[VEC_EPILOG_ITER_CHECK]]:
@@ -312,7 +312,7 @@ define void @foo_i32_no_bw(i64 %n) {
 ; CHECK-V2-IC4:  [[VEC_EPILOG_PH]]:
 ; CHECK-V2-IC4:    br label %[[VEC_EPILOG_VECTOR_BODY:.*]]
 ; CHECK-V2-IC4:  [[VEC_EPILOG_VECTOR_BODY]]:
-; CHECK-V2-IC4:    br i1 [[TMP11:%.*]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP20:![0-9]+]]
+; CHECK-V2-IC4:    br i1 [[TMP13:%.*]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP20:![0-9]+]]
 ; CHECK-V2-IC4:  [[VEC_EPILOG_MIDDLE_BLOCK]]:
 ; CHECK-V2-IC4:    br i1 [[CMP_N10:%.*]], label %[[FOR_COND_CLEANUP]], label %[[VEC_EPILOG_SCALAR_PH]]
 ; CHECK-V2-IC4:  [[VEC_EPILOG_SCALAR_PH]]:
@@ -366,17 +366,17 @@ for.cond.cleanup:
 ; CHECK-V1-IC1-FORCE-EPI2: [[META4]] = !{!"llvm.loop.estimated_trip_count", i32 128}
 ; CHECK-V1-IC1-FORCE-EPI2: [[PROF5]] = !{!"branch_weights", i32 1, i32 7}
 ; CHECK-V1-IC1-FORCE-EPI2: [[PROF6]] = !{!"branch_weights", i32 2, i32 6}
-; CHECK-V1-IC1-FORCE-EPI2: [[LOOP7]] = distinct !{[[LOOP7]], [[META2]], [[META8:![0-9]+]], [[META3]]}
-; CHECK-V1-IC1-FORCE-EPI2: [[META8]] = !{!"llvm.loop.estimated_trip_count", i32 0}
-; CHECK-V1-IC1-FORCE-EPI2: [[PROF9]] = !{!"branch_weights", i32 1, i32 1}
-; CHECK-V1-IC1-FORCE-EPI2: [[PROF10]] = !{!"branch_weights", i32 1, i32 0}
-; CHECK-V1-IC1-FORCE-EPI2: [[LOOP11]] = distinct !{[[LOOP11]], [[META3]], [[META2]], [[META8]]}
+; CHECK-V1-IC1-FORCE-EPI2: [[PROF7]] = !{!"branch_weights", i32 1, i32 0}
+; CHECK-V1-IC1-FORCE-EPI2: [[LOOP8]] = distinct !{[[LOOP8]], [[META2]], [[META9:![0-9]+]], [[META3]]}
+; CHECK-V1-IC1-FORCE-EPI2: [[META9]] = !{!"llvm.loop.estimated_trip_count", i32 0}
+; CHECK-V1-IC1-FORCE-EPI2: [[PROF10]] = !{!"branch_weights", i32 1, i32 1}
+; CHECK-V1-IC1-FORCE-EPI2: [[LOOP11]] = distinct !{[[LOOP11]], [[META3]], [[META2]], [[META9]]}
 ; CHECK-V1-IC1-FORCE-EPI2: [[PROF12]] = !{!"branch_weights", i32 1, i32 31}
 ; CHECK-V1-IC1-FORCE-EPI2: [[LOOP13]] = distinct !{[[LOOP13]], [[META2]], [[META3]], [[META14:![0-9]+]]}
 ; CHECK-V1-IC1-FORCE-EPI2: [[META14]] = !{!"llvm.loop.estimated_trip_count", i32 32}
 ; CHECK-V1-IC1-FORCE-EPI2: [[PROF15]] = !{!"branch_weights", i32 2, i32 30}
-; CHECK-V1-IC1-FORCE-EPI2: [[LOOP16]] = distinct !{[[LOOP16]], [[META2]], [[META8]], [[META3]]}
-; CHECK-V1-IC1-FORCE-EPI2: [[LOOP17]] = distinct !{[[LOOP17]], [[META3]], [[META2]], [[META8]]}
+; CHECK-V1-IC1-FORCE-EPI2: [[LOOP16]] = distinct !{[[LOOP16]], [[META2]], [[META9]], [[META3]]}
+; CHECK-V1-IC1-FORCE-EPI2: [[LOOP17]] = distinct !{[[LOOP17]], [[META3]], [[META2]], [[META9]]}
 ; CHECK-V1-IC1-FORCE-EPI2: [[LOOP18]] = distinct !{[[LOOP18]], [[META2]], [[META3]]}
 ; CHECK-V1-IC1-FORCE-EPI2: [[LOOP19]] = distinct !{[[LOOP19]], [[META2]], [[META3]]}
 ; CHECK-V1-IC1-FORCE-EPI2: [[LOOP20]] = distinct !{[[LOOP20]], [[META3]], [[META2]]}
@@ -409,17 +409,17 @@ for.cond.cleanup:
 ; CHECK-V2-IC4: [[META5]] = !{!"llvm.loop.estimated_trip_count", i32 64}
 ; CHECK-V2-IC4: [[PROF6]] = !{!"branch_weights", i32 1, i32 15}
 ; CHECK-V2-IC4: [[PROF7]] = !{!"branch_weights", i32 4, i32 12}
-; CHECK-V2-IC4: [[LOOP8]] = distinct !{[[LOOP8]], [[META3]], [[META9:![0-9]+]], [[META4]]}
-; CHECK-V2-IC4: [[META9]] = !{!"llvm.loop.estimated_trip_count", i32 0}
-; CHECK-V2-IC4: [[PROF10]] = !{!"branch_weights", i32 1, i32 3}
-; CHECK-V2-IC4: [[PROF11]] = !{!"branch_weights", i32 1, i32 0}
-; CHECK-V2-IC4: [[LOOP12]] = distinct !{[[LOOP12]], [[META4]], [[META3]], [[META9]]}
+; CHECK-V2-IC4: [[PROF8]] = !{!"branch_weights", i32 1, i32 0}
+; CHECK-V2-IC4: [[LOOP9]] = distinct !{[[LOOP9]], [[META3]], [[META10:![0-9]+]], [[META4]]}
+; CHECK-V2-IC4: [[META10]] = !{!"llvm.loop.estimated_trip_count", i32 0}
+; CHECK-V2-IC4: [[PROF11]] = !{!"branch_weights", i32 1, i32 3}
+; CHECK-V2-IC4: [[LOOP12]] = distinct !{[[LOOP12]], [[META4]], [[META3]], [[META10]]}
 ; CHECK-V2-IC4: [[LOOP13]] = distinct !{[[LOOP13]], [[META3]], [[META4]], [[META14:![0-9]+]]}
 ; CHECK-V2-IC4: [[META14]] = !{!"llvm.loop.estimated_trip_count", i32 16}
 ; CHECK-V2-IC4: [[PROF15]] = !{!"branch_weights", i32 8, i32 56}
-; CHECK-V2-IC4: [[LOOP16]] = distinct !{[[LOOP16]], [[META3]], [[META9]], [[META4]]}
+; CHECK-V2-IC4: [[LOOP16]] = distinct !{[[LOOP16]], [[META3]], [[META10]], [[META4]]}
 ; CHECK-V2-IC4: [[PROF17]] = !{!"branch_weights", i32 1, i32 7}
-; CHECK-V2-IC4: [[LOOP18]] = distinct !{[[LOOP18]], [[META4]], [[META3]], [[META9]]}
+; CHECK-V2-IC4: [[LOOP18]] = distinct !{[[LOOP18]], [[META4]], [[META3]], [[META10]]}
 ; CHECK-V2-IC4: [[LOOP19]] = distinct !{[[LOOP19]], [[META3]], [[META4]]}
 ; CHECK-V2-IC4: [[LOOP20]] = distinct !{[[LOOP20]], [[META3]], [[META4]]}
 ; CHECK-V2-IC4: [[LOOP21]] = distinct !{[[LOOP21]], [[META4]], [[META3]]}
diff --git a/llvm/unittests/Transforms/Utils/LoopUtilsTest.cpp b/llvm/unittests/Transforms/Utils/LoopUtilsTest.cpp
index a17d26aa51ce6..61b0dc79f88de 100644
--- a/llvm/unittests/Transforms/Utils/LoopUtilsTest.cpp
+++ b/llvm/unittests/Transforms/Utils/LoopUtilsTest.cpp
@@ -221,8 +221,8 @@ TEST(LoopUtils, zeroEstimatedTripCount) {
 
   // With EstimatedLoopInvocationWeight, setLoopEstimatedTripCount sets branch
   // weights and llvm.loop.estimated_trip_count all to 0, so
-  // getLoopEstimatedTripCount returns std::nullopt.  It does not touch other
-  // loop metadata, if any.
+  // getLoopEstimatedTripCount returns 0.  It does not touch other loop
+  // metadata, if any.
   std::unique_ptr<Module> M = parseIR(C, IR);
   run(*M, "foo",
       [&](Function &F, DominatorTree &DT, ScalarEvolution &SE, LoopInfo &LI) {
@@ -242,14 +242,14 @@ TEST(LoopUtils, zeroEstimatedTripCount) {
           EXPECT_EQ(getOptionalIntLoopAttribute(L, "foo"), Foo);
           EXPECT_EQ(getOptionalIntLoopAttribute(L, LLVMLoopEstimatedTripCount),
                     0);
-          EXPECT_EQ(getLoopEstimatedTripCount(L), std::nullopt);
+          EXPECT_EQ(getLoopEstimatedTripCount(L), 0);
         }
       });
 
   // Without EstimatedLoopInvocationWeight, setLoopEstimatedTripCount sets
-  // llvm.loop.estimated_trip_count to 0, so getLoopEstimatedTripCount returns
-  // std::nullopt.  It does not touch branch weights or other loop metadata, if
-  // any.
+  // llvm.loop.estimated_trip_count to 0, so getLoopEstimatedTripCount returns 0
+  // even for the loops that have no latch branch weights.  It does not touch
+  // branch weights or other loop metadata, if any.
   M = parseIR(C, IR);
   run(*M, "foo",
       [&](Function &F, DominatorTree &DT, ScalarEvolution &SE, LoopInfo &LI) {
@@ -271,7 +271,7 @@ TEST(LoopUtils, zeroEstimatedTripCount) {
           EXPECT_EQ(getOptionalIntLoopAttribute(L, "foo"), Foo);
           EXPECT_EQ(getOptionalIntLoopAttribute(L, LLVMLoopEstimatedTripCount),
                     0);
-          EXPECT_EQ(getLoopEstimatedTripCount(L), std::nullopt);
+          EXPECT_EQ(getLoopEstimatedTripCount(L), 0);
         }
       });
 }

>From ebdf38c0e693c312256894d959b889d3d7d7990d Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Wed, 19 Aug 2026 18:33:09 +0100
Subject: [PATCH 3/4] !fixup update more stale checks

---
 .../LoopVectorize/branch-weights.ll           | 33 +++++++++----------
 1 file changed, 15 insertions(+), 18 deletions(-)

diff --git a/llvm/test/Transforms/LoopVectorize/branch-weights.ll b/llvm/test/Transforms/LoopVectorize/branch-weights.ll
index e8e95bccf0413..9aeeaa9dc479a 100644
--- a/llvm/test/Transforms/LoopVectorize/branch-weights.ll
+++ b/llvm/test/Transforms/LoopVectorize/branch-weights.ll
@@ -298,7 +298,7 @@ define void @f2(ptr %p, i64 %n) !prof !0 {
 ; MAINVF4IC1_EPI4:    br label %[[VEC_EPILOG_VECTOR_BODY:.*]]
 ; MAINVF4IC1_EPI4:  [[VEC_EPILOG_VECTOR_BODY]]:
 ; MAINVF4IC1_EPI4:    [[TMP3:%.*]] = icmp eq i64 [[INDEX_NEXT5:%.*]], [[N_VEC3:%.*]]
-; MAINVF4IC1_EPI4:    br i1 [[TMP3]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP24:![0-9]+]]
+; MAINVF4IC1_EPI4:    br i1 [[TMP3]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !prof [[PROF10]], !llvm.loop [[LOOP24:![0-9]+]]
 ; MAINVF4IC1_EPI4:  [[VEC_EPILOG_MIDDLE_BLOCK]]:
 ; MAINVF4IC1_EPI4:    [[CMP_N6:%.*]] = icmp eq i64 [[N]], [[N_VEC3]]
 ; MAINVF4IC1_EPI4:    br i1 [[CMP_N6]], label %[[EXIT]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF13]]
@@ -332,7 +332,7 @@ define void @f2(ptr %p, i64 %n) !prof !0 {
 ; MAINVF4IC2_EPI4:    br label %[[VEC_EPILOG_VECTOR_BODY:.*]]
 ; MAINVF4IC2_EPI4:  [[VEC_EPILOG_VECTOR_BODY]]:
 ; MAINVF4IC2_EPI4:    [[TMP4:%.*]] = icmp eq i64 [[INDEX_NEXT5:%.*]], [[N_VEC3:%.*]]
-; MAINVF4IC2_EPI4:    br i1 [[TMP4]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP24:![0-9]+]]
+; MAINVF4IC2_EPI4:    br i1 [[TMP4]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !prof [[PROF10]], !llvm.loop [[LOOP24:![0-9]+]]
 ; MAINVF4IC2_EPI4:  [[VEC_EPILOG_MIDDLE_BLOCK]]:
 ; MAINVF4IC2_EPI4:    [[CMP_N6:%.*]] = icmp eq i64 [[N]], [[N_VEC3]]
 ; MAINVF4IC2_EPI4:    br i1 [[CMP_N6]], label %[[EXIT]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF13]]
@@ -366,7 +366,7 @@ define void @f2(ptr %p, i64 %n) !prof !0 {
 ; MAINVF8IC1_EPI2:    br label %[[VEC_EPILOG_VECTOR_BODY:.*]]
 ; MAINVF8IC1_EPI2:  [[VEC_EPILOG_VECTOR_BODY]]:
 ; MAINVF8IC1_EPI2:    [[TMP3:%.*]] = icmp eq i64 [[INDEX_NEXT5:%.*]], [[N_VEC3:%.*]]
-; MAINVF8IC1_EPI2:    br i1 [[TMP3]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP23:![0-9]+]]
+; MAINVF8IC1_EPI2:    br i1 [[TMP3]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !prof [[PROF10]], !llvm.loop [[LOOP23:![0-9]+]]
 ; MAINVF8IC1_EPI2:  [[VEC_EPILOG_MIDDLE_BLOCK]]:
 ; MAINVF8IC1_EPI2:    [[CMP_N6:%.*]] = icmp eq i64 [[N]], [[N_VEC3]]
 ; MAINVF8IC1_EPI2:    br i1 [[CMP_N6]], label %[[EXIT]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF13]]
@@ -405,7 +405,7 @@ define void @f3(ptr %p, i64 %n) !prof !0 {
 ; MAINVF4IC1_EPI4:    br label %[[VECTOR_BODY:.*]]
 ; MAINVF4IC1_EPI4:  [[VECTOR_BODY]]:
 ; MAINVF4IC1_EPI4:    [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT:%.*]], [[N_VEC:%.*]]
-; MAINVF4IC1_EPI4:    br i1 [[TMP2]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP26:![0-9]+]]
+; MAINVF4IC1_EPI4:    br i1 [[TMP2]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !prof [[PROF10]], !llvm.loop [[LOOP26:![0-9]+]]
 ; MAINVF4IC1_EPI4:  [[MIDDLE_BLOCK]]:
 ; MAINVF4IC1_EPI4:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
 ; MAINVF4IC1_EPI4:    br i1 [[CMP_N]], label %[[EXIT:.*]], label %[[VEC_EPILOG_ITER_CHECK:.*]], !prof [[PROF8]]
@@ -416,7 +416,7 @@ define void @f3(ptr %p, i64 %n) !prof !0 {
 ; MAINVF4IC1_EPI4:    br label %[[VEC_EPILOG_VECTOR_BODY:.*]]
 ; MAINVF4IC1_EPI4:  [[VEC_EPILOG_VECTOR_BODY]]:
 ; MAINVF4IC1_EPI4:    [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT4:%.*]], [[N_VEC2:%.*]]
-; MAINVF4IC1_EPI4:    br i1 [[TMP5]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP27:![0-9]+]]
+; MAINVF4IC1_EPI4:    br i1 [[TMP5]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !prof [[PROF10]], !llvm.loop [[LOOP27:![0-9]+]]
 ; MAINVF4IC1_EPI4:  [[VEC_EPILOG_MIDDLE_BLOCK]]:
 ; MAINVF4IC1_EPI4:    [[CMP_N5:%.*]] = icmp eq i64 [[N]], [[N_VEC2]]
 ; MAINVF4IC1_EPI4:    br i1 [[CMP_N5]], label %[[EXIT]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF13]]
@@ -424,7 +424,7 @@ define void @f3(ptr %p, i64 %n) !prof !0 {
 ; MAINVF4IC1_EPI4:    br label %[[LOOP:.*]]
 ; MAINVF4IC1_EPI4:  [[LOOP]]:
 ; MAINVF4IC1_EPI4:    [[CMP_LOOP:%.*]] = icmp eq i64 [[IV_NEXT:%.*]], [[N]]
-; MAINVF4IC1_EPI4:    br i1 [[CMP_LOOP]], label %[[EXIT]], label %[[LOOP]], !prof [[PROF28:![0-9]+]], !llvm.loop [[LOOP29:![0-9]+]]
+; MAINVF4IC1_EPI4:    br i1 [[CMP_LOOP]], label %[[EXIT]], label %[[LOOP]], !prof [[PROF10]], !llvm.loop [[LOOP28:![0-9]+]]
 ; MAINVF4IC1_EPI4:  [[EXIT]]:
 ;
 ; MAINVF4IC2_EPI4-LABEL: define void @f3(
@@ -439,7 +439,7 @@ define void @f3(ptr %p, i64 %n) !prof !0 {
 ; MAINVF4IC2_EPI4:    br label %[[VECTOR_BODY:.*]]
 ; MAINVF4IC2_EPI4:  [[VECTOR_BODY]]:
 ; MAINVF4IC2_EPI4:    [[TMP3:%.*]] = icmp eq i64 [[INDEX_NEXT:%.*]], [[N_VEC:%.*]]
-; MAINVF4IC2_EPI4:    br i1 [[TMP3]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP26:![0-9]+]]
+; MAINVF4IC2_EPI4:    br i1 [[TMP3]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !prof [[PROF10]], !llvm.loop [[LOOP26:![0-9]+]]
 ; MAINVF4IC2_EPI4:  [[MIDDLE_BLOCK]]:
 ; MAINVF4IC2_EPI4:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
 ; MAINVF4IC2_EPI4:    br i1 [[CMP_N]], label %[[EXIT:.*]], label %[[VEC_EPILOG_ITER_CHECK:.*]], !prof [[PROF8]]
@@ -450,7 +450,7 @@ define void @f3(ptr %p, i64 %n) !prof !0 {
 ; MAINVF4IC2_EPI4:    br label %[[VEC_EPILOG_VECTOR_BODY:.*]]
 ; MAINVF4IC2_EPI4:  [[VEC_EPILOG_VECTOR_BODY]]:
 ; MAINVF4IC2_EPI4:    [[TMP6:%.*]] = icmp eq i64 [[INDEX_NEXT4:%.*]], [[N_VEC2:%.*]]
-; MAINVF4IC2_EPI4:    br i1 [[TMP6]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP27:![0-9]+]]
+; MAINVF4IC2_EPI4:    br i1 [[TMP6]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !prof [[PROF10]], !llvm.loop [[LOOP27:![0-9]+]]
 ; MAINVF4IC2_EPI4:  [[VEC_EPILOG_MIDDLE_BLOCK]]:
 ; MAINVF4IC2_EPI4:    [[CMP_N5:%.*]] = icmp eq i64 [[N]], [[N_VEC2]]
 ; MAINVF4IC2_EPI4:    br i1 [[CMP_N5]], label %[[EXIT]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF13]]
@@ -458,7 +458,7 @@ define void @f3(ptr %p, i64 %n) !prof !0 {
 ; MAINVF4IC2_EPI4:    br label %[[LOOP:.*]]
 ; MAINVF4IC2_EPI4:  [[LOOP]]:
 ; MAINVF4IC2_EPI4:    [[CMP_LOOP:%.*]] = icmp eq i64 [[IV_NEXT:%.*]], [[N]]
-; MAINVF4IC2_EPI4:    br i1 [[CMP_LOOP]], label %[[EXIT]], label %[[LOOP]], !prof [[PROF28:![0-9]+]], !llvm.loop [[LOOP29:![0-9]+]]
+; MAINVF4IC2_EPI4:    br i1 [[CMP_LOOP]], label %[[EXIT]], label %[[LOOP]], !prof [[PROF10]], !llvm.loop [[LOOP28:![0-9]+]]
 ; MAINVF4IC2_EPI4:  [[EXIT]]:
 ;
 ; MAINVF8IC1_EPI2-LABEL: define void @f3(
@@ -473,7 +473,7 @@ define void @f3(ptr %p, i64 %n) !prof !0 {
 ; MAINVF8IC1_EPI2:    br label %[[VECTOR_BODY:.*]]
 ; MAINVF8IC1_EPI2:  [[VECTOR_BODY]]:
 ; MAINVF8IC1_EPI2:    [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT:%.*]], [[N_VEC:%.*]]
-; MAINVF8IC1_EPI2:    br i1 [[TMP2]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP26:![0-9]+]]
+; MAINVF8IC1_EPI2:    br i1 [[TMP2]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !prof [[PROF10]], !llvm.loop [[LOOP26:![0-9]+]]
 ; MAINVF8IC1_EPI2:  [[MIDDLE_BLOCK]]:
 ; MAINVF8IC1_EPI2:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
 ; MAINVF8IC1_EPI2:    br i1 [[CMP_N]], label %[[EXIT:.*]], label %[[VEC_EPILOG_ITER_CHECK:.*]], !prof [[PROF8]]
@@ -484,7 +484,7 @@ define void @f3(ptr %p, i64 %n) !prof !0 {
 ; MAINVF8IC1_EPI2:    br label %[[VEC_EPILOG_VECTOR_BODY:.*]]
 ; MAINVF8IC1_EPI2:  [[VEC_EPILOG_VECTOR_BODY]]:
 ; MAINVF8IC1_EPI2:    [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT4:%.*]], [[N_VEC2:%.*]]
-; MAINVF8IC1_EPI2:    br i1 [[TMP5]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP27:![0-9]+]]
+; MAINVF8IC1_EPI2:    br i1 [[TMP5]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !prof [[PROF10]], !llvm.loop [[LOOP27:![0-9]+]]
 ; MAINVF8IC1_EPI2:  [[VEC_EPILOG_MIDDLE_BLOCK]]:
 ; MAINVF8IC1_EPI2:    [[CMP_N5:%.*]] = icmp eq i64 [[N]], [[N_VEC2]]
 ; MAINVF8IC1_EPI2:    br i1 [[CMP_N5]], label %[[EXIT]], label %[[VEC_EPILOG_SCALAR_PH]], !prof [[PROF13]]
@@ -492,7 +492,7 @@ define void @f3(ptr %p, i64 %n) !prof !0 {
 ; MAINVF8IC1_EPI2:    br label %[[LOOP:.*]]
 ; MAINVF8IC1_EPI2:  [[LOOP]]:
 ; MAINVF8IC1_EPI2:    [[CMP_LOOP:%.*]] = icmp eq i64 [[IV_NEXT:%.*]], [[N]]
-; MAINVF8IC1_EPI2:    br i1 [[CMP_LOOP]], label %[[EXIT]], label %[[LOOP]], !prof [[PROF28:![0-9]+]], !llvm.loop [[LOOP29:![0-9]+]]
+; MAINVF8IC1_EPI2:    br i1 [[CMP_LOOP]], label %[[EXIT]], label %[[LOOP]], !prof [[PROF10]], !llvm.loop [[LOOP28:![0-9]+]]
 ; MAINVF8IC1_EPI2:  [[EXIT]]:
 ;
 entry:
@@ -550,8 +550,7 @@ exit:
 ; MAINVF4IC1_EPI4: [[LOOP25]] = distinct !{[[LOOP25]], [[META6]], [[META5]], [[META12]]}
 ; MAINVF4IC1_EPI4: [[LOOP26]] = distinct !{[[LOOP26]], [[META12]], [[META5]], [[META6]]}
 ; MAINVF4IC1_EPI4: [[LOOP27]] = distinct !{[[LOOP27]], [[META12]], [[META5]], [[META6]]}
-; MAINVF4IC1_EPI4: [[PROF28]] = !{!"branch_weights", i32 1, i32 1023}
-; MAINVF4IC1_EPI4: [[LOOP29]] = distinct !{[[LOOP29]], [[META12]], [[META6]], [[META5]]}
+; MAINVF4IC1_EPI4: [[LOOP28]] = distinct !{[[LOOP28]], [[META12]], [[META6]], [[META5]]}
 ;.
 ; MAINVF4IC2_EPI4: [[PROF0]] = !{!"function_entry_count", i64 13}
 ; MAINVF4IC2_EPI4: [[PROF1]] = !{!"branch_weights", i32 12, i32 1}
@@ -581,8 +580,7 @@ exit:
 ; MAINVF4IC2_EPI4: [[LOOP25]] = distinct !{[[LOOP25]], [[META6]], [[META5]], [[META12]]}
 ; MAINVF4IC2_EPI4: [[LOOP26]] = distinct !{[[LOOP26]], [[META12]], [[META5]], [[META6]]}
 ; MAINVF4IC2_EPI4: [[LOOP27]] = distinct !{[[LOOP27]], [[META12]], [[META5]], [[META6]]}
-; MAINVF4IC2_EPI4: [[PROF28]] = !{!"branch_weights", i32 1, i32 1023}
-; MAINVF4IC2_EPI4: [[LOOP29]] = distinct !{[[LOOP29]], [[META12]], [[META6]], [[META5]]}
+; MAINVF4IC2_EPI4: [[LOOP28]] = distinct !{[[LOOP28]], [[META12]], [[META6]], [[META5]]}
 ;.
 ; MAINVF8IC1_EPI2: [[PROF0]] = !{!"function_entry_count", i64 13}
 ; MAINVF8IC1_EPI2: [[PROF1]] = !{!"branch_weights", i32 12, i32 1}
@@ -612,6 +610,5 @@ exit:
 ; MAINVF8IC1_EPI2: [[LOOP25]] = distinct !{[[LOOP25]], [[META6]], [[META5]], [[META24]]}
 ; MAINVF8IC1_EPI2: [[LOOP26]] = distinct !{[[LOOP26]], [[META24]], [[META5]], [[META6]]}
 ; MAINVF8IC1_EPI2: [[LOOP27]] = distinct !{[[LOOP27]], [[META24]], [[META5]], [[META6]]}
-; MAINVF8IC1_EPI2: [[PROF28]] = !{!"branch_weights", i32 1, i32 1023}
-; MAINVF8IC1_EPI2: [[LOOP29]] = distinct !{[[LOOP29]], [[META24]], [[META6]], [[META5]]}
+; MAINVF8IC1_EPI2: [[LOOP28]] = distinct !{[[LOOP28]], [[META24]], [[META6]], [[META5]]}
 ;.

>From 843f4b78fca2fe05b8c767c1c61ccc41207572b3 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Thu, 20 Aug 2026 17:21:40 +0100
Subject: [PATCH 4/4] !fixup add another test combination

---
 ...-trip-count.ll => estimated-trip-count.ll} | 67 +++++++++++++++++++
 .../vectorize-zero-estimated-trip-count.ll    |  2 +-
 2 files changed, 68 insertions(+), 1 deletion(-)
 rename llvm/test/Transforms/LoopUnroll/{zero-estimated-trip-count.ll => estimated-trip-count.ll} (66%)

diff --git a/llvm/test/Transforms/LoopUnroll/zero-estimated-trip-count.ll b/llvm/test/Transforms/LoopUnroll/estimated-trip-count.ll
similarity index 66%
rename from llvm/test/Transforms/LoopUnroll/zero-estimated-trip-count.ll
rename to llvm/test/Transforms/LoopUnroll/estimated-trip-count.ll
index 17403f4f76897..f822250026450 100644
--- a/llvm/test/Transforms/LoopUnroll/zero-estimated-trip-count.ll
+++ b/llvm/test/Transforms/LoopUnroll/estimated-trip-count.ll
@@ -106,12 +106,69 @@ exit:
   ret void
 }
 
+; Loop with a high estimated trip count, but branch weights that almost always
+; exit the loop.
+define void @high_estimated_trip_count_low_branch_weights(ptr %p, i64 %n) !prof !0 {
+; CHECK-LABEL: define void @high_estimated_trip_count_low_branch_weights(
+; CHECK-SAME: ptr [[P:%.*]], i64 [[N:%.*]]) !prof [[PROF0]] {
+; CHECK:  [[ENTRY:.*:]]
+; CHECK:    br i1 [[TMP1:%.*]], label %[[LOOP_EPIL_PREHEADER:.*]], label %[[ENTRY_NEW:.*]], !prof [[PROF12:![0-9]+]]
+; CHECK:  [[ENTRY_NEW]]:
+; CHECK:    br label %[[LOOP:.*]]
+; CHECK:  [[LOOP]]:
+; CHECK:    br i1 [[NITER_NCMP_7:%.*]], label %[[EXIT_UNR_LCSSA:.*]], label %[[LOOP]], !prof [[PROF12]], !llvm.loop [[LOOP13:![0-9]+]]
+; CHECK:  [[EXIT_UNR_LCSSA]]:
+; CHECK:    br i1 [[LCMP_MOD:%.*]], label %[[LOOP_EPIL_PREHEADER]], label %[[EXIT:.*]], !prof [[PROF14:![0-9]+]]
+; CHECK:  [[LOOP_EPIL_PREHEADER]]:
+; CHECK:    br label %[[LOOP_EPIL:.*]]
+; CHECK:  [[LOOP_EPIL]]:
+; CHECK:    br i1 [[EPIL_ITER_CMP:%.*]], label %[[LOOP_EPIL]], label %[[EXIT_EPILOG_LCSSA:.*]], !prof [[PROF14]], !llvm.loop [[LOOP15:![0-9]+]]
+; CHECK:  [[EXIT_EPILOG_LCSSA]]:
+; CHECK:    br label %[[EXIT]]
+; CHECK:  [[EXIT]]:
+;
+; FORCED-LABEL: define void @high_estimated_trip_count_low_branch_weights(
+; FORCED-SAME: ptr [[P:%.*]], i64 [[N:%.*]]) !prof [[PROF0]] {
+; FORCED:  [[ENTRY:.*:]]
+; FORCED:    br i1 [[TMP1:%.*]], label %[[LOOP_EPIL_PREHEADER:.*]], label %[[ENTRY_NEW:.*]], !prof [[PROF12:![0-9]+]]
+; FORCED:  [[ENTRY_NEW]]:
+; FORCED:    br label %[[LOOP:.*]]
+; FORCED:  [[LOOP]]:
+; FORCED:    br i1 [[NITER_NCMP_3:%.*]], label %[[EXIT_UNR_LCSSA:.*]], label %[[LOOP]], !prof [[PROF13:![0-9]+]], !llvm.loop [[LOOP14:![0-9]+]]
+; FORCED:  [[EXIT_UNR_LCSSA]]:
+; FORCED:    br i1 [[LCMP_MOD:%.*]], label %[[LOOP_EPIL_PREHEADER]], label %[[EXIT:.*]], !prof [[PROF15:![0-9]+]]
+; FORCED:  [[LOOP_EPIL_PREHEADER]]:
+; FORCED:    br label %[[LOOP_EPIL:.*]]
+; FORCED:  [[LOOP_EPIL]]:
+; FORCED:    br i1 [[EPIL_ITER_CMP:%.*]], label %[[LOOP_EPIL]], label %[[EXIT_EPILOG_LCSSA:.*]], !prof [[PROF16:![0-9]+]], !llvm.loop [[LOOP17:![0-9]+]]
+; FORCED:  [[EXIT_EPILOG_LCSSA]]:
+; FORCED:    br label %[[EXIT]]
+; FORCED:  [[EXIT]]:
+;
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+  %ptr = getelementptr inbounds i32, ptr %p, i64 %iv
+  %v = load i32, ptr %ptr
+  %add = add i32 %v, 1
+  store i32 %add, ptr %ptr
+  %iv.next = add i64 %iv, 1
+  %cmp.loop = icmp eq i64 %iv.next, %n
+  br i1 %cmp.loop, label %exit, label %loop, !prof !6, !llvm.loop !3
+
+exit:
+  ret void
+}
+
 !0 = !{!"function_entry_count", i64 1000}
 !1 = !{!"branch_weights", i32 1, i32 1023}
 !2 = distinct !{!2, !4}
 !3 = distinct !{!3, !5}
 !4 = !{!"llvm.loop.estimated_trip_count", i32 0}
 !5 = !{!"llvm.loop.estimated_trip_count", i32 1024}
+!6 = !{!"branch_weights", i32 1023, i32 1}
 ;.
 ; CHECK: [[PROF0]] = !{!"function_entry_count", i64 1000}
 ; CHECK: [[PROF1]] = !{!"branch_weights", i32 1, i32 1023}
@@ -125,6 +182,10 @@ exit:
 ; CHECK: [[PROF9]] = !{!"branch_weights", i32 1610087680, i32 537395968}
 ; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META3]], [[META11:![0-9]+]]}
 ; CHECK: [[META11]] = !{!"llvm.loop.unroll.disable"}
+; CHECK: [[PROF12]] = !{!"branch_weights", i32 -2147483648, i32 0}
+; CHECK: [[LOOP13]] = distinct !{[[LOOP13]], [[META7]]}
+; CHECK: [[PROF14]] = !{!"branch_weights", i32 2097152, i32 2145386496}
+; CHECK: [[LOOP15]] = distinct !{[[LOOP15]], [[META3]], [[META11]]}
 ;.
 ; FORCED: [[PROF0]] = !{!"function_entry_count", i64 1000}
 ; FORCED: [[PROF1]] = !{!"branch_weights", i32 6285314, i32 2141198334}
@@ -138,4 +199,10 @@ exit:
 ; FORCED: [[LOOP9]] = distinct !{[[LOOP9]], [[META10:![0-9]+]], [[META5]]}
 ; FORCED: [[META10]] = !{!"llvm.loop.estimated_trip_count", i32 256}
 ; FORCED: [[LOOP11]] = distinct !{[[LOOP11]], [[META4]], [[META5]]}
+; FORCED: [[PROF12]] = !{!"branch_weights", i32 2147483646, i32 2}
+; FORCED: [[PROF13]] = !{!"branch_weights", i32 -2147483648, i32 0}
+; FORCED: [[LOOP14]] = distinct !{[[LOOP14]], [[META10]], [[META5]]}
+; FORCED: [[PROF15]] = !{!"branch_weights", i32 2097152, i32 2145386496}
+; FORCED: [[PROF16]] = !{!"branch_weights", i32 2097146, i32 2145386502}
+; FORCED: [[LOOP17]] = distinct !{[[LOOP17]], [[META4]], [[META5]]}
 ;.
diff --git a/llvm/test/Transforms/LoopVectorize/vectorize-zero-estimated-trip-count.ll b/llvm/test/Transforms/LoopVectorize/vectorize-zero-estimated-trip-count.ll
index 1bcc04449ad16..a7dbf1da58c6c 100644
--- a/llvm/test/Transforms/LoopVectorize/vectorize-zero-estimated-trip-count.ll
+++ b/llvm/test/Transforms/LoopVectorize/vectorize-zero-estimated-trip-count.ll
@@ -3,6 +3,7 @@
 ; an outer loop.
 
 ; REQUIRES: x86-registered-target
+; REQUIRES: asserts
 ; RUN: opt -passes=loop-vectorize -S %s | FileCheck %s
 
 ; A zero estimated trip count means the outer loop is estimated not to be
@@ -11,7 +12,6 @@
 ; is used instead.
 ; RUN: opt -passes=loop-vectorize -disable-output -debug-only=loop-vectorize %s \
 ; RUN:   2>&1 | FileCheck %s -check-prefix=COST
-; REQUIRES: asserts
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"



More information about the llvm-commits mailing list