[llvm] [Transforms][Utils] Preserve branch weights in LoopSplitUtils (PR #213626)

Ashutosh Nema via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 3 02:51:08 PDT 2026


https://github.com/nema-ashutosh updated https://github.com/llvm/llvm-project/pull/213626

>From c63eb508e311580e26a41ded43d2568227129844 Mon Sep 17 00:00:00 2001
From: Ashutosh Nema <ashu1212 at gmail.com>
Date: Mon, 3 Aug 2026 14:32:40 +0530
Subject: [PATCH 1/2] [Transforms][Utils] Preserve branch weights in
 LoopSplitUtils

Carry the original latch's branch weights onto the clamped latch, and
mark the newly created partition-guard branches as having unknown
weights so profile-tracking passes are not misled.
---
 llvm/lib/Transforms/Utils/LoopSplitUtils.cpp | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/LoopSplitUtils.cpp b/llvm/lib/Transforms/Utils/LoopSplitUtils.cpp
index 1c8ea08ac80c6..24295f6867dc6 100644
--- a/llvm/lib/Transforms/Utils/LoopSplitUtils.cpp
+++ b/llvm/lib/Transforms/Utils/LoopSplitUtils.cpp
@@ -60,6 +60,7 @@
 #include "llvm/IR/Function.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Instructions.h"
+#include "llvm/IR/ProfDataUtils.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Transforms/Utils/Cloning.h"
@@ -506,7 +507,17 @@ static void rewriteLatch(Loop *PL, Value *IndOp, Value *SelEnd,
                                                /*Inclusive=*/!LatchComparesPHI);
   Value *NewCmp = B.CreateICmp(Pred, IndOp, Bound, "itr.chk");
   B.SetInsertPoint(Term);
-  B.CreateCondBr(NewCmp, PL->getHeader(), Exit);
+  auto *NewBr = B.CreateCondBr(NewCmp, PL->getHeader(), Exit);
+  // Carry the original latch's branch weights onto the clamped latch, matching
+  // by which original successor stayed in the loop (the "keep iterating" edge).
+  SmallVector<uint32_t, 2> Weights;
+  if (extractBranchWeights(*Term, Weights)) {
+    bool Succ0InLoop = PL->contains(Term->getSuccessor(0));
+    setBranchWeights(*NewBr,
+                     {Succ0InLoop ? Weights[0] : Weights[1],
+                      Succ0InLoop ? Weights[1] : Weights[0]},
+                     /*IsExpected=*/false);
+  }
   Term->eraseFromParent();
   if (Cmp->use_empty())
     Cmp->eraseFromParent();
@@ -551,7 +562,10 @@ void LoopSplitUtils::chainPartitions(SplitState &S) {
       B.CreateBr(P.Preheader);
     } else {
       Value *Enter = B.CreateICmp(GuardPred, P.StartVal, P.SelEnd, "itr.chk");
-      B.CreateCondBr(Enter, P.Preheader, MergeAfter);
+      auto *GuardBr = B.CreateCondBr(Enter, P.Preheader, MergeAfter);
+      // New control flow with no source profile; record the weights as unknown
+      // so profile-tracking passes are not misled.
+      setExplicitlyUnknownBranchWeightsIfProfiled(*GuardBr, DEBUG_TYPE);
     }
     GuardTerm->eraseFromParent();
 

>From 78682bc1c72a8af8fc962ab99b576e3e3e096a3c Mon Sep 17 00:00:00 2001
From: Ashutosh Nema <ashu1212 at gmail.com>
Date: Mon, 3 Aug 2026 15:20:28 +0530
Subject: [PATCH 2/2] [Transforms][Utils] Preserve branch weights in
 LoopSplitUtils

Code cleanup to use extractBranchWeights overload
---
 llvm/lib/Transforms/Utils/LoopSplitUtils.cpp | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/LoopSplitUtils.cpp b/llvm/lib/Transforms/Utils/LoopSplitUtils.cpp
index 24295f6867dc6..db07e3f571f66 100644
--- a/llvm/lib/Transforms/Utils/LoopSplitUtils.cpp
+++ b/llvm/lib/Transforms/Utils/LoopSplitUtils.cpp
@@ -508,15 +508,14 @@ static void rewriteLatch(Loop *PL, Value *IndOp, Value *SelEnd,
   Value *NewCmp = B.CreateICmp(Pred, IndOp, Bound, "itr.chk");
   B.SetInsertPoint(Term);
   auto *NewBr = B.CreateCondBr(NewCmp, PL->getHeader(), Exit);
-  // Carry the original latch's branch weights onto the clamped latch, matching
-  // by which original successor stayed in the loop (the "keep iterating" edge).
-  SmallVector<uint32_t, 2> Weights;
-  if (extractBranchWeights(*Term, Weights)) {
+  // Carry the original latch's weights over, mapping by which successor stayed
+  // in the loop.
+  uint64_t TrueW, FalseW;
+  if (extractBranchWeights(*Term, TrueW, FalseW)) {
     bool Succ0InLoop = PL->contains(Term->getSuccessor(0));
-    setBranchWeights(*NewBr,
-                     {Succ0InLoop ? Weights[0] : Weights[1],
-                      Succ0InLoop ? Weights[1] : Weights[0]},
-                     /*IsExpected=*/false);
+    setFittedBranchWeights(
+        *NewBr, {Succ0InLoop ? TrueW : FalseW, Succ0InLoop ? FalseW : TrueW},
+        /*IsExpected=*/false);
   }
   Term->eraseFromParent();
   if (Cmp->use_empty())



More information about the llvm-commits mailing list