[llvm] [LoopVectorize] Compute BlockFrequencyInfo eagerly to fix assertion failure (PR #215237)

Karthika Devi C via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 10 06:02:31 PDT 2026


https://github.com/kartcq updated https://github.com/llvm/llvm-project/pull/215237

>From 1435a866d11762526ba9696e1bae87fcf14986a0 Mon Sep 17 00:00:00 2001
From: Karthika Devi C <kartc at qti.qualcomm.com>
Date: Mon, 10 Aug 2026 03:20:50 -0700
Subject: [PATCH 1/3] [LoopVectorize] Compute BlockFrequencyInfo eagerly to fix
 assertion failure

After a6af12620778, LoopVectorizePass crashes when processing
functions with multiple loops. The lazy BFI lambda requests
BlockFrequencyAnalysis after earlier loops have been vectorized,
at which point the cached CycleInfo holds stale pointers to
blocks that no longer exist in the function.

Compute BFI eagerly at the top of run(), before runImpl()
mutates the function, so that CycleInfo is read while the CFG
is still consistent.

Fixes #215236
---
 llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 3c65eda187a6e..bc313849b7b82 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -8478,8 +8478,14 @@ PreservedAnalyses LoopVectorizePass::run(Function &F,
 
   auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
   PSI = MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
-  GetBFI = [&AM, &F]() -> BlockFrequencyInfo & {
-    return AM.getResult<BlockFrequencyAnalysis>(F);
+  // Compute BFI eagerly rather than lazily. LoopVectorize may modify the
+  // function (vectorizing earlier loops) before requesting BFI for later loops.
+  // If BFI is computed lazily after such modifications, its dependency
+  // CycleAnalysis may be stale (holding pointers to deleted blocks), causing
+  // crashes.
+  BlockFrequencyInfo &BFIRef = AM.getResult<BlockFrequencyAnalysis>(F);
+  GetBFI = [&BFIRef]() -> BlockFrequencyInfo & {
+    return BFIRef;
   };
   LoopVectorizeResult Result = runImpl(F);
   if (!Result.MadeAnyChange)

>From ff5a6dfa183d3a593fe4b2bd939b1073a14ce54a Mon Sep 17 00:00:00 2001
From: Karthika Devi C <kartc at qti.qualcomm.com>
Date: Mon, 10 Aug 2026 04:48:39 -0700
Subject: [PATCH 2/3] NFC: clang-format LoopVectorize.cpp

---
 llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index bc313849b7b82..1333724b755a6 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -8484,9 +8484,7 @@ PreservedAnalyses LoopVectorizePass::run(Function &F,
   // CycleAnalysis may be stale (holding pointers to deleted blocks), causing
   // crashes.
   BlockFrequencyInfo &BFIRef = AM.getResult<BlockFrequencyAnalysis>(F);
-  GetBFI = [&BFIRef]() -> BlockFrequencyInfo & {
-    return BFIRef;
-  };
+  GetBFI = [&BFIRef]() -> BlockFrequencyInfo & { return BFIRef; };
   LoopVectorizeResult Result = runImpl(F);
   if (!Result.MadeAnyChange)
     return PreservedAnalyses::all();

>From 0245aa32550651c677fa4c6ad6a95349cb2a18d0 Mon Sep 17 00:00:00 2001
From: Karthika Devi C <kartc at qti.qualcomm.com>
Date: Mon, 10 Aug 2026 05:22:32 -0700
Subject: [PATCH 3/3] Add regression test for BFI crash

---
 .../LoopVectorize/bfi-stale-crash.ll          | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 llvm/test/Transforms/LoopVectorize/bfi-stale-crash.ll

diff --git a/llvm/test/Transforms/LoopVectorize/bfi-stale-crash.ll b/llvm/test/Transforms/LoopVectorize/bfi-stale-crash.ll
new file mode 100644
index 0000000000000..6ff84b3268139
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/bfi-stale-crash.ll
@@ -0,0 +1,52 @@
+; RUN: opt < %s -passes='dse,loop-vectorize' -S | FileCheck %s
+;
+; Verify that LoopVectorize does not crash when BlockFrequencyInfo is computed
+; after an earlier loop has been vectorized and a prior pass (DSE) has cached
+; CycleAnalysis.
+;
+; CHECK-LABEL: @InitializeMasks(
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"
+target triple = "aarch64-unknown-linux-gnu"
+
+ at clear_mask = external global [65 x i64]
+
+define void @InitializeMasks(ptr %mask_1) {
+entry:
+  br label %for.body
+
+for.body:
+  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+  %arrayidx = getelementptr [8 x i8], ptr @clear_mask, i64 %indvars.iv
+  store i64 1, ptr %arrayidx, align 8
+  %indvars.iv.next = add i64 %indvars.iv, 1
+  %exitcond.not = icmp eq i64 %indvars.iv.next, 64
+  br i1 %exitcond.not, label %for.end, label %for.body
+
+for.end:
+  store i64 0, ptr %mask_1, align 8
+  br label %for.body98
+
+for.body98:
+  %indvars.iv3551 = phi i64 [ 0, %for.end ], [ %indvars.iv.next356, %for.inc140 ]
+  %indvars.iv.next356 = add i64 %indvars.iv3551, 1
+  %cmp107 = icmp ugt i64 %indvars.iv3551, 15
+  br i1 %cmp107, label %if.end, label %if.end.thread
+
+if.end.thread:
+  store i64 0, ptr %mask_1, align 8
+  br label %for.inc140
+
+if.end:
+  br i1 false, label %if.end.if.then128_crit_edge, label %for.inc140
+
+if.end.if.then128_crit_edge:
+  ret void
+
+for.inc140:
+  %exitcond358.not = icmp eq i64 %indvars.iv3551, 56
+  br i1 %exitcond358.not, label %for.cond180.loopexit.7, label %for.body98
+
+for.cond180.loopexit.7:
+  ret void
+}



More information about the llvm-commits mailing list