[llvm] [CodeGenPrepare] Use recomputed split-branch weights. (PR #199822)
via llvm-commits
llvm-commits at lists.llvm.org
Tue May 26 20:50:22 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Justin Lebar (jlebar)
<details>
<summary>Changes</summary>
splitBranchCondition computes new branch weights after splitting an
and/or condition into two branches, but then passed the original weights
to createBranchWeights at each metadata update. The recomputed values
were discarded.
Pass the scaled NewTrueWeight/NewFalseWeight values when installing
metadata on both generated branches.
This bug was found by a large run of Opus 4.7 looking for bugs in LLVM.
---
Full diff: https://github.com/llvm/llvm-project/pull/199822.diff
2 Files Affected:
- (modified) llvm/lib/CodeGen/CodeGenPrepare.cpp (+4-4)
- (added) llvm/test/Transforms/CodeGenPrepare/X86/split-branch-cond-weights.ll (+66)
``````````diff
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 9b756dc7b03b7..8a278d60882ac 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -9447,7 +9447,7 @@ bool CodeGenPrepare::splitBranchCondition(Function &F) {
scaleWeights(NewTrueWeight, NewFalseWeight);
Br1->setMetadata(LLVMContext::MD_prof,
MDBuilder(Br1->getContext())
- .createBranchWeights(TrueWeight, FalseWeight,
+ .createBranchWeights(NewTrueWeight, NewFalseWeight,
hasBranchWeightOrigin(*Br1)));
NewTrueWeight = TrueWeight;
@@ -9455,7 +9455,7 @@ bool CodeGenPrepare::splitBranchCondition(Function &F) {
scaleWeights(NewTrueWeight, NewFalseWeight);
Br2->setMetadata(LLVMContext::MD_prof,
MDBuilder(Br2->getContext())
- .createBranchWeights(TrueWeight, FalseWeight));
+ .createBranchWeights(NewTrueWeight, NewFalseWeight));
}
} else {
// Codegen X & Y as:
@@ -9483,14 +9483,14 @@ bool CodeGenPrepare::splitBranchCondition(Function &F) {
scaleWeights(NewTrueWeight, NewFalseWeight);
Br1->setMetadata(LLVMContext::MD_prof,
MDBuilder(Br1->getContext())
- .createBranchWeights(TrueWeight, FalseWeight));
+ .createBranchWeights(NewTrueWeight, NewFalseWeight));
NewTrueWeight = 2 * TrueWeight;
NewFalseWeight = FalseWeight;
scaleWeights(NewTrueWeight, NewFalseWeight);
Br2->setMetadata(LLVMContext::MD_prof,
MDBuilder(Br2->getContext())
- .createBranchWeights(TrueWeight, FalseWeight));
+ .createBranchWeights(NewTrueWeight, NewFalseWeight));
}
}
diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/split-branch-cond-weights.ll b/llvm/test/Transforms/CodeGenPrepare/X86/split-branch-cond-weights.ll
new file mode 100644
index 0000000000000..1d33ff3c5bafa
--- /dev/null
+++ b/llvm/test/Transforms/CodeGenPrepare/X86/split-branch-cond-weights.ll
@@ -0,0 +1,66 @@
+; RUN: llc -fast-isel -stop-after=codegenprepare -mtriple=x86_64-unknown-linux-gnu -o - < %s | FileCheck %s
+
+; Verify that CodeGenPrepare::splitBranchCondition installs the freshly
+; computed (and scaled) branch weights on the two resulting branches.
+;
+; For an `or` of two conditions with original weights (A, B), the comment
+; in splitBranchCondition prescribes:
+; Br1 weights = (A, A + 2*B)
+; Br2 weights = (A, 2*B)
+;
+; For an `and` of two conditions with original weights (A, B):
+; Br1 weights = (2*A + B, B)
+; Br2 weights = (2*A, B)
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @a()
+declare void @b()
+
+; CHECK-LABEL: define void @split_or
+; CHECK: br i1 %c1, label %t, label %entry.cond.split, !prof [[OR_BR1:![0-9]+]]
+; CHECK: br i1 %c2, label %t, label %f, !prof [[OR_BR2:![0-9]+]]
+define void @split_or(i32 %x, i32 %y) {
+entry:
+ %c1 = icmp eq i32 %x, 0
+ %c2 = icmp eq i32 %y, 0
+ %or = or i1 %c1, %c2
+ br i1 %or, label %t, label %f, !prof !0
+t:
+ call void @a()
+ ret void
+f:
+ call void @b()
+ ret void
+}
+
+; CHECK-LABEL: define void @split_and
+; CHECK: br i1 %c1, label %entry.cond.split, label %f, !prof [[AND_BR1:![0-9]+]]
+; CHECK: br i1 %c2, label %t, label %f, !prof [[AND_BR2:![0-9]+]]
+define void @split_and(i32 %x, i32 %y) {
+entry:
+ %c1 = icmp eq i32 %x, 0
+ %c2 = icmp eq i32 %y, 0
+ %and = and i1 %c1, %c2
+ br i1 %and, label %t, label %f, !prof !0
+t:
+ call void @a()
+ ret void
+f:
+ call void @b()
+ ret void
+}
+
+!0 = !{!"branch_weights", i32 100, i32 7}
+
+; Expected freshly-computed weights:
+; OR Br1: (100, 100 + 2*7) = (100, 114)
+; OR Br2: (100, 2*7) = (100, 14)
+; AND Br1: (2*100 + 7, 7) = (207, 7)
+; AND Br2: (2*100, 7) = (200, 7)
+
+; CHECK-DAG: [[OR_BR1]] = !{!"branch_weights", i32 100, i32 114}
+; CHECK-DAG: [[OR_BR2]] = !{!"branch_weights", i32 100, i32 14}
+; CHECK-DAG: [[AND_BR1]] = !{!"branch_weights", i32 207, i32 7}
+; CHECK-DAG: [[AND_BR2]] = !{!"branch_weights", i32 200, i32 7}
``````````
</details>
https://github.com/llvm/llvm-project/pull/199822
More information about the llvm-commits
mailing list