[llvm] [SimplifyCFG] Probabilities associated with same condition are constant (PR #155734)
Mircea Trofin via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 4 10:28:25 PDT 2025
https://github.com/mtrofin updated https://github.com/llvm/llvm-project/pull/155734
>From 9d2d78ed91505fde9069ae0b684a3fded495b2a6 Mon Sep 17 00:00:00 2001
From: Mircea Trofin <mtrofin at google.com>
Date: Thu, 28 Aug 2025 01:15:02 +0000
Subject: [PATCH] [SimplifyCFG] Probabilities associated with same condition
are constant
---
llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 21 +---
.../SimplifyCFG/preserve-branchweights.ll | 99 +++++++++----------
2 files changed, 54 insertions(+), 66 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 02d6393dd5815..86d4750f6f000 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -4812,23 +4812,12 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI,
SelectInst *NV = cast<SelectInst>(
Builder.CreateSelect(PBICond, PBIV, BIV, PBIV->getName() + ".mux"));
PN.setIncomingValue(PBBIdx, NV);
- // Although the select has the same condition as PBI, the original branch
- // weights for PBI do not apply to the new select because the select's
- // 'logical' edges are incoming edges of the phi that is eliminated, not
- // the outgoing edges of PBI.
+ // The select has the same condition as PBI, in the same BB. The
+ // probabilities don't change.
if (HasWeights) {
- uint64_t PredCommon = PBIOp ? PredFalseWeight : PredTrueWeight;
- uint64_t PredOther = PBIOp ? PredTrueWeight : PredFalseWeight;
- uint64_t SuccCommon = BIOp ? SuccFalseWeight : SuccTrueWeight;
- uint64_t SuccOther = BIOp ? SuccTrueWeight : SuccFalseWeight;
- // The weight to PredCommonDest should be PredCommon * SuccTotal.
- // The weight to PredOtherDest should be PredOther * SuccCommon.
- uint64_t NewWeights[2] = {PredCommon * (SuccCommon + SuccOther),
- PredOther * SuccCommon};
-
- fitWeights(NewWeights);
-
- setBranchWeights(NV, NewWeights[0], NewWeights[1],
+ uint64_t TrueWeight = PBIOp ? PredFalseWeight : PredTrueWeight;
+ uint64_t FalseWeight = PBIOp ? PredTrueWeight : PredFalseWeight;
+ setBranchWeights(NV, TrueWeight, FalseWeight,
/*IsExpected=*/false);
}
}
diff --git a/llvm/test/Transforms/SimplifyCFG/preserve-branchweights.ll b/llvm/test/Transforms/SimplifyCFG/preserve-branchweights.ll
index 0f78e236b4248..19988a330d237 100644
--- a/llvm/test/Transforms/SimplifyCFG/preserve-branchweights.ll
+++ b/llvm/test/Transforms/SimplifyCFG/preserve-branchweights.ll
@@ -610,10 +610,10 @@ define i32 @SimplifyCondBranchToCondBranchSwapMissingWeight(i1 %cmpa, i1 %cmpb)
; CHECK-NEXT: [[CMPA_NOT:%.*]] = xor i1 [[CMPA:%.*]], true
; CHECK-NEXT: [[CMPB_NOT:%.*]] = xor i1 [[CMPB:%.*]], true
; CHECK-NEXT: [[BRMERGE:%.*]] = select i1 [[CMPA_NOT]], i1 true, i1 [[CMPB_NOT]]
-; CHECK-NEXT: [[DOTMUX:%.*]] = select i1 [[CMPA_NOT]], i32 0, i32 2, !prof [[PROF17:![0-9]+]]
-; CHECK-NEXT: [[OUTVAL:%.*]] = select i1 [[BRMERGE]], i32 [[DOTMUX]], i32 1, !prof [[PROF18:![0-9]+]]
+; CHECK-NEXT: [[DOTMUX:%.*]] = select i1 [[CMPA_NOT]], i32 0, i32 2, !prof [[PROF15]]
+; CHECK-NEXT: [[OUTVAL:%.*]] = select i1 [[BRMERGE]], i32 [[DOTMUX]], i32 1, !prof [[PROF17:![0-9]+]]
; CHECK-NEXT: ret i32 [[OUTVAL]]
-;
+
block1:
br i1 %cmpa, label %block2, label %block3, !prof !13
@@ -636,7 +636,7 @@ define void @or_icmps_harmful(i32 %x, i32 %y, ptr %p) {
; CHECK-LABEL: @or_icmps_harmful(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[EXPECTED_TRUE:%.*]] = icmp sgt i32 [[X:%.*]], -1
-; CHECK-NEXT: br i1 [[EXPECTED_TRUE]], label [[EXIT:%.*]], label [[RARE:%.*]], !prof [[PROF19:![0-9]+]]
+; CHECK-NEXT: br i1 [[EXPECTED_TRUE]], label [[EXIT:%.*]], label [[RARE:%.*]], !prof [[PROF18:![0-9]+]]
; CHECK: rare:
; CHECK-NEXT: [[EXPENSIVE:%.*]] = icmp eq i32 [[Y:%.*]], 0
; CHECK-NEXT: br i1 [[EXPENSIVE]], label [[EXIT]], label [[FALSE:%.*]]
@@ -669,7 +669,7 @@ define void @or_icmps_harmful_inverted(i32 %x, i32 %y, ptr %p) {
; CHECK-LABEL: @or_icmps_harmful_inverted(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[EXPECTED_FALSE:%.*]] = icmp sgt i32 [[X:%.*]], -1
-; CHECK-NEXT: br i1 [[EXPECTED_FALSE]], label [[RARE:%.*]], label [[EXIT:%.*]], !prof [[PROF20:![0-9]+]]
+; CHECK-NEXT: br i1 [[EXPECTED_FALSE]], label [[RARE:%.*]], label [[EXIT:%.*]], !prof [[PROF19:![0-9]+]]
; CHECK: rare:
; CHECK-NEXT: [[EXPENSIVE:%.*]] = icmp eq i32 [[Y:%.*]], 0
; CHECK-NEXT: br i1 [[EXPENSIVE]], label [[EXIT]], label [[FALSE:%.*]]
@@ -702,7 +702,7 @@ define void @or_icmps_probably_not_harmful(i32 %x, i32 %y, ptr %p) {
; CHECK-NEXT: [[EXPECTED_TRUE:%.*]] = icmp sgt i32 [[X:%.*]], -1
; CHECK-NEXT: [[EXPENSIVE:%.*]] = icmp eq i32 [[Y:%.*]], 0
; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[EXPECTED_TRUE]], i1 true, i1 [[EXPENSIVE]]
-; CHECK-NEXT: br i1 [[OR_COND]], label [[EXIT:%.*]], label [[FALSE:%.*]], !prof [[PROF21:![0-9]+]], !unpredictable [[META22:![0-9]+]]
+; CHECK-NEXT: br i1 [[OR_COND]], label [[EXIT:%.*]], label [[FALSE:%.*]], !prof [[PROF20:![0-9]+]], !unpredictable [[META21:![0-9]+]]
; CHECK: false:
; CHECK-NEXT: store i8 42, ptr [[P:%.*]], align 1
; CHECK-NEXT: br label [[EXIT]]
@@ -734,7 +734,7 @@ define void @or_icmps_not_that_harmful(i32 %x, i32 %y, ptr %p) {
; CHECK-NEXT: [[EXPECTED_TRUE:%.*]] = icmp sgt i32 [[X:%.*]], -1
; CHECK-NEXT: [[EXPENSIVE:%.*]] = icmp eq i32 [[Y:%.*]], 0
; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[EXPECTED_TRUE]], i1 true, i1 [[EXPENSIVE]]
-; CHECK-NEXT: br i1 [[OR_COND]], label [[EXIT:%.*]], label [[FALSE:%.*]], !prof [[PROF23:![0-9]+]]
+; CHECK-NEXT: br i1 [[OR_COND]], label [[EXIT:%.*]], label [[FALSE:%.*]], !prof [[PROF22:![0-9]+]]
; CHECK: false:
; CHECK-NEXT: store i8 42, ptr [[P:%.*]], align 1
; CHECK-NEXT: br label [[EXIT]]
@@ -766,7 +766,7 @@ define void @or_icmps_not_that_harmful_inverted(i32 %x, i32 %y, ptr %p) {
; CHECK-NEXT: [[EXPECTED_TRUE:%.*]] = icmp sgt i32 [[X:%.*]], -1
; CHECK-NEXT: [[EXPENSIVE:%.*]] = icmp eq i32 [[Y:%.*]], 0
; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[EXPECTED_TRUE]], i1 true, i1 [[EXPENSIVE]]
-; CHECK-NEXT: br i1 [[OR_COND]], label [[EXIT:%.*]], label [[FALSE:%.*]], !prof [[PROF24:![0-9]+]]
+; CHECK-NEXT: br i1 [[OR_COND]], label [[EXIT:%.*]], label [[FALSE:%.*]], !prof [[PROF23:![0-9]+]]
; CHECK: false:
; CHECK-NEXT: store i8 42, ptr [[P:%.*]], align 1
; CHECK-NEXT: br label [[EXIT]]
@@ -797,7 +797,7 @@ define void @or_icmps_useful(i32 %x, i32 %y, ptr %p) {
; CHECK-NEXT: [[EXPECTED_TRUE:%.*]] = icmp sle i32 [[X:%.*]], -1
; CHECK-NEXT: [[EXPENSIVE:%.*]] = icmp eq i32 [[Y:%.*]], 0
; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[EXPECTED_TRUE]], i1 true, i1 [[EXPENSIVE]]
-; CHECK-NEXT: br i1 [[OR_COND]], label [[EXIT:%.*]], label [[FALSE:%.*]], !prof [[PROF25:![0-9]+]]
+; CHECK-NEXT: br i1 [[OR_COND]], label [[EXIT:%.*]], label [[FALSE:%.*]], !prof [[PROF24:![0-9]+]]
; CHECK: false:
; CHECK-NEXT: store i8 42, ptr [[P:%.*]], align 1
; CHECK-NEXT: br label [[EXIT]]
@@ -828,7 +828,7 @@ define void @or_icmps_useful_inverted(i32 %x, i32 %y, ptr %p) {
; CHECK-NEXT: [[EXPECTED_FALSE:%.*]] = icmp sgt i32 [[X:%.*]], -1
; CHECK-NEXT: [[EXPENSIVE:%.*]] = icmp eq i32 [[Y:%.*]], 0
; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[EXPECTED_FALSE]], i1 true, i1 [[EXPENSIVE]]
-; CHECK-NEXT: br i1 [[OR_COND]], label [[EXIT:%.*]], label [[FALSE:%.*]], !prof [[PROF25]]
+; CHECK-NEXT: br i1 [[OR_COND]], label [[EXIT:%.*]], label [[FALSE:%.*]], !prof [[PROF24]]
; CHECK: false:
; CHECK-NEXT: store i8 42, ptr [[P:%.*]], align 1
; CHECK-NEXT: br label [[EXIT]]
@@ -889,7 +889,7 @@ define void @and_icmps_harmful(i32 %x, i32 %y, ptr %p) {
; CHECK-LABEL: @and_icmps_harmful(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[EXPECTED_FALSE:%.*]] = icmp sgt i32 [[X:%.*]], -1
-; CHECK-NEXT: br i1 [[EXPECTED_FALSE]], label [[RARE:%.*]], label [[EXIT:%.*]], !prof [[PROF20]]
+; CHECK-NEXT: br i1 [[EXPECTED_FALSE]], label [[RARE:%.*]], label [[EXIT:%.*]], !prof [[PROF19]]
; CHECK: rare:
; CHECK-NEXT: [[EXPENSIVE:%.*]] = icmp eq i32 [[Y:%.*]], 0
; CHECK-NEXT: br i1 [[EXPENSIVE]], label [[FALSE:%.*]], label [[EXIT]]
@@ -922,7 +922,7 @@ define void @and_icmps_harmful_inverted(i32 %x, i32 %y, ptr %p) {
; CHECK-LABEL: @and_icmps_harmful_inverted(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[EXPECTED_TRUE:%.*]] = icmp sgt i32 [[X:%.*]], -1
-; CHECK-NEXT: br i1 [[EXPECTED_TRUE]], label [[EXIT:%.*]], label [[RARE:%.*]], !prof [[PROF19]]
+; CHECK-NEXT: br i1 [[EXPECTED_TRUE]], label [[EXIT:%.*]], label [[RARE:%.*]], !prof [[PROF18]]
; CHECK: rare:
; CHECK-NEXT: [[EXPENSIVE:%.*]] = icmp eq i32 [[Y:%.*]], 0
; CHECK-NEXT: br i1 [[EXPENSIVE]], label [[FALSE:%.*]], label [[EXIT]]
@@ -957,7 +957,7 @@ define void @and_icmps_not_that_harmful(i32 %x, i32 %y, ptr %p) {
; CHECK-NEXT: [[EXPECTED_FALSE:%.*]] = icmp sgt i32 [[X:%.*]], -1
; CHECK-NEXT: [[EXPENSIVE:%.*]] = icmp eq i32 [[Y:%.*]], 0
; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[EXPECTED_FALSE]], i1 [[EXPENSIVE]], i1 false
-; CHECK-NEXT: br i1 [[OR_COND]], label [[FALSE:%.*]], label [[EXIT:%.*]], !prof [[PROF26:![0-9]+]]
+; CHECK-NEXT: br i1 [[OR_COND]], label [[FALSE:%.*]], label [[EXIT:%.*]], !prof [[PROF25:![0-9]+]]
; CHECK: false:
; CHECK-NEXT: store i8 42, ptr [[P:%.*]], align 1
; CHECK-NEXT: br label [[EXIT]]
@@ -989,7 +989,7 @@ define void @and_icmps_not_that_harmful_inverted(i32 %x, i32 %y, ptr %p) {
; CHECK-NEXT: [[EXPECTED_TRUE:%.*]] = icmp sle i32 [[X:%.*]], -1
; CHECK-NEXT: [[EXPENSIVE:%.*]] = icmp eq i32 [[Y:%.*]], 0
; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[EXPECTED_TRUE]], i1 [[EXPENSIVE]], i1 false
-; CHECK-NEXT: br i1 [[OR_COND]], label [[FALSE:%.*]], label [[EXIT:%.*]], !prof [[PROF26]]
+; CHECK-NEXT: br i1 [[OR_COND]], label [[FALSE:%.*]], label [[EXIT:%.*]], !prof [[PROF25]]
; CHECK: false:
; CHECK-NEXT: store i8 42, ptr [[P:%.*]], align 1
; CHECK-NEXT: br label [[EXIT]]
@@ -1020,7 +1020,7 @@ define void @and_icmps_useful(i32 %x, i32 %y, ptr %p) {
; CHECK-NEXT: [[EXPECTED_TRUE:%.*]] = icmp sgt i32 [[X:%.*]], -1
; CHECK-NEXT: [[EXPENSIVE:%.*]] = icmp eq i32 [[Y:%.*]], 0
; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[EXPECTED_TRUE]], i1 [[EXPENSIVE]], i1 false
-; CHECK-NEXT: br i1 [[OR_COND]], label [[FALSE:%.*]], label [[EXIT:%.*]], !prof [[PROF27:![0-9]+]]
+; CHECK-NEXT: br i1 [[OR_COND]], label [[FALSE:%.*]], label [[EXIT:%.*]], !prof [[PROF26:![0-9]+]]
; CHECK: false:
; CHECK-NEXT: store i8 42, ptr [[P:%.*]], align 1
; CHECK-NEXT: br label [[EXIT]]
@@ -1051,7 +1051,7 @@ define void @and_icmps_useful_inverted(i32 %x, i32 %y, ptr %p) {
; CHECK-NEXT: [[EXPECTED_FALSE:%.*]] = icmp sle i32 [[X:%.*]], -1
; CHECK-NEXT: [[EXPENSIVE:%.*]] = icmp eq i32 [[Y:%.*]], 0
; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[EXPECTED_FALSE]], i1 [[EXPENSIVE]], i1 false
-; CHECK-NEXT: br i1 [[OR_COND]], label [[FALSE:%.*]], label [[EXIT:%.*]], !prof [[PROF27]]
+; CHECK-NEXT: br i1 [[OR_COND]], label [[FALSE:%.*]], label [[EXIT:%.*]], !prof [[PROF26]]
; CHECK: false:
; CHECK-NEXT: store i8 42, ptr [[P:%.*]], align 1
; CHECK-NEXT: br label [[EXIT]]
@@ -1096,37 +1096,36 @@ exit:
!19 = !{!"branch_weights", i32 0, i32 0}
!20 = !{}
-;.
-; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind uwtable }
-; CHECK: attributes #[[ATTR1]] = { nounwind }
-; CHECK: attributes #[[ATTR2:[0-9]+]] = { noredzone nounwind ssp memory(none) }
-;.
-; CHECK: [[PROF0]] = !{!"branch_weights", i32 5, i32 11}
-; CHECK: [[PROF1]] = !{!"branch_weights", i32 1, i32 5}
-; CHECK: [[PROF2]] = !{!"branch_weights", i32 1, i32 3}
-; CHECK: [[PROF3]] = !{!"branch_weights", i32 7, i32 1, i32 2}
-; CHECK: [[PROF4]] = !{!"branch_weights", i32 49, i32 12, i32 24, i32 35}
-; CHECK: [[PROF5]] = !{!"branch_weights", i32 11, i32 5}
-; CHECK: [[PROF6]] = !{!"branch_weights", i32 17, i32 15}
-; CHECK: [[PROF7]] = !{!"branch_weights", i32 9, i32 7}
-; CHECK: [[PROF8]] = !{!"branch_weights", i32 17, i32 9, i32 8, i32 7, i32 17}
-; CHECK: [[PROF9]] = !{!"branch_weights", i32 24, i32 33}
-; CHECK: [[PROF10]] = !{!"branch_weights", i32 8, i32 33}
-; CHECK: [[PROF11]] = !{!"branch_weights", i32 112017436, i32 -735157296}
-; CHECK: [[PROF12]] = !{!"branch_weights", i32 3, i32 5}
-; CHECK: [[PROF13]] = !{!"branch_weights", i32 22, i32 12}
-; CHECK: [[PROF14]] = !{!"branch_weights", i32 34, i32 21}
-; CHECK: [[PROF15]] = !{!"branch_weights", i32 33, i32 14}
-; CHECK: [[PROF16]] = !{!"branch_weights", i32 47, i32 8}
-; CHECK: [[PROF17]] = !{!"branch_weights", i32 6, i32 2}
-; CHECK: [[PROF18]] = !{!"branch_weights", i32 8, i32 2}
-; CHECK: [[PROF19]] = !{!"branch_weights", i32 99, i32 1}
-; CHECK: [[PROF20]] = !{!"branch_weights", i32 1, i32 99}
-; CHECK: [[PROF21]] = !{!"branch_weights", i32 199, i32 1}
-; CHECK: [[META22]] = !{}
-; CHECK: [[PROF23]] = !{!"branch_weights", i32 197, i32 1}
-; CHECK: [[PROF24]] = !{!"branch_weights", i32 100, i32 98}
-; CHECK: [[PROF25]] = !{!"branch_weights", i32 101, i32 99}
-; CHECK: [[PROF26]] = !{!"branch_weights", i32 1, i32 197}
-; CHECK: [[PROF27]] = !{!"branch_weights", i32 99, i32 101}
-;.
+.
+CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind uwtable }
+CHECK: attributes #[[ATTR1]] = { nounwind }
+CHECK: attributes #[[ATTR2:[0-9]+]] = { noredzone nounwind ssp memory(none) }
+.
+CHECK: [[PROF0]] = !{!"branch_weights", i32 5, i32 11}
+CHECK: [[PROF1]] = !{!"branch_weights", i32 1, i32 5}
+CHECK: [[PROF2]] = !{!"branch_weights", i32 1, i32 3}
+CHECK: [[PROF3]] = !{!"branch_weights", i32 7, i32 1, i32 2}
+CHECK: [[PROF4]] = !{!"branch_weights", i32 49, i32 12, i32 24, i32 35}
+CHECK: [[PROF5]] = !{!"branch_weights", i32 11, i32 5}
+CHECK: [[PROF6]] = !{!"branch_weights", i32 17, i32 15}
+CHECK: [[PROF7]] = !{!"branch_weights", i32 9, i32 7}
+CHECK: [[PROF8]] = !{!"branch_weights", i32 17, i32 9, i32 8, i32 7, i32 17}
+CHECK: [[PROF9]] = !{!"branch_weights", i32 24, i32 33}
+CHECK: [[PROF10]] = !{!"branch_weights", i32 8, i32 33}
+CHECK: [[PROF11]] = !{!"branch_weights", i32 112017436, i32 -735157296}
+CHECK: [[PROF12]] = !{!"branch_weights", i32 3, i32 5}
+CHECK: [[PROF13]] = !{!"branch_weights", i32 2, i32 3}
+CHECK: [[PROF14]] = !{!"branch_weights", i32 34, i32 21}
+CHECK: [[PROF15]] = !{!"branch_weights", i32 3, i32 2}
+CHECK: [[PROF16]] = !{!"branch_weights", i32 47, i32 8}
+CHECK: [[PROF17]] = !{!"branch_weights", i32 8, i32 2}
+CHECK: [[PROF18]] = !{!"branch_weights", i32 99, i32 1}
+CHECK: [[PROF19]] = !{!"branch_weights", i32 1, i32 99}
+CHECK: [[PROF20]] = !{!"branch_weights", i32 199, i32 1}
+CHECK: [[META21]] = !{}
+CHECK: [[PROF22]] = !{!"branch_weights", i32 197, i32 1}
+CHECK: [[PROF23]] = !{!"branch_weights", i32 100, i32 98}
+CHECK: [[PROF24]] = !{!"branch_weights", i32 101, i32 99}
+CHECK: [[PROF25]] = !{!"branch_weights", i32 1, i32 197}
+CHECK: [[PROF26]] = !{!"branch_weights", i32 99, i32 101}
+.
More information about the llvm-commits
mailing list