[llvm] c4763e2 - [profcheck][InstCombine] Preserve branch weights in logical identities (#165810)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 3 09:32:45 PST 2025
Author: Alan Zhao
Date: 2025-11-03T09:32:42-08:00
New Revision: c4763e2b9038fbd1154f0276a8b9542b8c115111
URL: https://github.com/llvm/llvm-project/commit/c4763e2b9038fbd1154f0276a8b9542b8c115111
DIFF: https://github.com/llvm/llvm-project/commit/c4763e2b9038fbd1154f0276a8b9542b8c115111.diff
LOG: [profcheck][InstCombine] Preserve branch weights in logical identities (#165810)
For the simplification
```
(C && A) || (!C && B) --> sel C, A, B
```
(and related), if `C` (or (`!C`)) is the condition in the select
instruction representing the logical and, we can preserve that logical
and's branch weights when emitting the new instruction. Otherwise, the
profile data is unknown.
If `C` is the condition of both logical ands, then we just take the
branch weights of the first logical and (though in practice they should
be equal.)
Furthermore, `select-safe-transforms.ii` now passes under the profcheck
configuration, so we remove it from the failing tests.
Tracking issue: #147390
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
llvm/test/Transforms/InstCombine/select-safe-transforms.ll
llvm/utils/profcheck-xfail.txt
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index f5130da818746..9572f9d702e1b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -3599,6 +3599,21 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {
m_Not(m_Specific(SelCond->getTrueValue())));
if (MayNeedFreeze)
C = Builder.CreateFreeze(C);
+ if (!ProfcheckDisableMetadataFixes) {
+ Value *C2 = nullptr, *A2 = nullptr, *B2 = nullptr;
+ if (match(CondVal, m_LogicalAnd(m_Specific(C), m_Value(A2))) &&
+ SelCond) {
+ return SelectInst::Create(C, A, B, "", nullptr, SelCond);
+ } else if (match(FalseVal,
+ m_LogicalAnd(m_Not(m_Value(C2)), m_Value(B2))) &&
+ SelFVal) {
+ SelectInst *NewSI = SelectInst::Create(C, A, B, "", nullptr, SelFVal);
+ NewSI->swapProfMetadata();
+ return NewSI;
+ } else {
+ return createSelectInstWithUnknownProfile(C, A, B);
+ }
+ }
return SelectInst::Create(C, A, B);
}
@@ -3615,6 +3630,20 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {
m_Not(m_Specific(SelFVal->getTrueValue())));
if (MayNeedFreeze)
C = Builder.CreateFreeze(C);
+ if (!ProfcheckDisableMetadataFixes) {
+ Value *C2 = nullptr, *A2 = nullptr, *B2 = nullptr;
+ if (match(CondVal, m_LogicalAnd(m_Not(m_Value(C2)), m_Value(A2))) &&
+ SelCond) {
+ SelectInst *NewSI = SelectInst::Create(C, B, A, "", nullptr, SelCond);
+ NewSI->swapProfMetadata();
+ return NewSI;
+ } else if (match(FalseVal, m_LogicalAnd(m_Specific(C), m_Value(B2))) &&
+ SelFVal) {
+ return SelectInst::Create(C, B, A, "", nullptr, SelFVal);
+ } else {
+ return createSelectInstWithUnknownProfile(C, B, A);
+ }
+ }
return SelectInst::Create(C, B, A);
}
}
diff --git a/llvm/test/Transforms/InstCombine/select-safe-transforms.ll b/llvm/test/Transforms/InstCombine/select-safe-transforms.ll
index 3d97048f43127..8b3c0502ac04d 100644
--- a/llvm/test/Transforms/InstCombine/select-safe-transforms.ll
+++ b/llvm/test/Transforms/InstCombine/select-safe-transforms.ll
@@ -256,27 +256,27 @@ define <2 x i1> @not_logical_or2(i1 %b, <2 x i32> %a) {
ret <2 x i1> %and
}
-define i1 @bools_logical_commute0(i1 %a, i1 %b, i1 %c) {
+define i1 @bools_logical_commute0(i1 %a, i1 %b, i1 %c) !prof !0 {
; CHECK-LABEL: @bools_logical_commute0(
-; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]
+; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]], !prof [[PROF2]]
; CHECK-NEXT: ret i1 [[OR]]
;
%not = xor i1 %c, -1
- %and1 = select i1 %not, i1 %a, i1 false
- %and2 = select i1 %c, i1 %b, i1 false
- %or = select i1 %and1, i1 true, i1 %and2
+ %and1 = select i1 %not, i1 %a, i1 false, !prof!1
+ %and2 = select i1 %c, i1 %b, i1 false, !prof !2
+ %or = select i1 %and1, i1 true, i1 %and2, !prof !3
ret i1 %or
}
-define i1 @bools_logical_commute0_and1(i1 %a, i1 %b, i1 %c) {
+define i1 @bools_logical_commute0_and1(i1 %a, i1 %b, i1 %c) !prof !0 {
; CHECK-LABEL: @bools_logical_commute0_and1(
-; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]
+; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]], !prof [[PROF1]]
; CHECK-NEXT: ret i1 [[OR]]
;
%not = xor i1 %c, -1
%and1 = and i1 %not, %a
- %and2 = select i1 %c, i1 %b, i1 false
- %or = select i1 %and1, i1 true, i1 %and2
+ %and2 = select i1 %c, i1 %b, i1 false, !prof !1
+ %or = select i1 %and1, i1 true, i1 %and2, !prof !2
ret i1 %or
}
@@ -292,15 +292,15 @@ define i1 @bools_logical_commute0_and2(i1 %a, i1 %b, i1 %c) {
ret i1 %or
}
-define i1 @bools_logical_commute0_and1_and2(i1 %a, i1 %b, i1 %c) {
+define i1 @bools_logical_commute0_and1_and2(i1 %a, i1 %b, i1 %c) !prof !0 {
; CHECK-LABEL: @bools_logical_commute0_and1_and2(
-; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]
+; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]], !prof [[PROF3:![0-9]+]]
; CHECK-NEXT: ret i1 [[OR]]
;
%not = xor i1 %c, -1
%and1 = and i1 %not, %a
%and2 = and i1 %c, %b
- %or = select i1 %and1, i1 true, i1 %and2
+ %or = select i1 %and1, i1 true, i1 %and2, !prof !1
ret i1 %or
}
@@ -457,27 +457,27 @@ define i1 @bools_logical_commute3_and1_and2(i1 %b, i1 %c) {
ret i1 %or
}
-define i1 @bools2_logical_commute0(i1 %a, i1 %b, i1 %c) {
+define i1 @bools2_logical_commute0(i1 %a, i1 %b, i1 %c) !prof !0 {
; CHECK-LABEL: @bools2_logical_commute0(
-; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]
+; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]], !prof [[PROF1]]
; CHECK-NEXT: ret i1 [[OR]]
;
%not = xor i1 %c, -1
- %and1 = select i1 %c, i1 %a, i1 false
- %and2 = select i1 %not, i1 %b, i1 false
- %or = select i1 %and1, i1 true, i1 %and2
+ %and1 = select i1 %c, i1 %a, i1 false, !prof !1
+ %and2 = select i1 %not, i1 %b, i1 false, !prof !2
+ %or = select i1 %and1, i1 true, i1 %and2, !prof !3
ret i1 %or
}
-define i1 @bools2_logical_commute0_and1(i1 %a, i1 %b, i1 %c) {
+define i1 @bools2_logical_commute0_and1(i1 %a, i1 %b, i1 %c) !prof !0 {
; CHECK-LABEL: @bools2_logical_commute0_and1(
-; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]
+; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]], !prof [[PROF2]]
; CHECK-NEXT: ret i1 [[OR]]
;
%not = xor i1 %c, -1
%and1 = and i1 %c, %a
- %and2 = select i1 %not, i1 %b, i1 false
- %or = select i1 %and1, i1 true, i1 %and2
+ %and2 = select i1 %not, i1 %b, i1 false, !prof !1
+ %or = select i1 %and1, i1 true, i1 %and2, !prof !2
ret i1 %or
}
@@ -493,15 +493,15 @@ define i1 @bools2_logical_commute0_and2(i1 %a, i1 %b, i1 %c) {
ret i1 %or
}
-define i1 @bools2_logical_commute0_and1_and2(i1 %a, i1 %b, i1 %c) {
+define i1 @bools2_logical_commute0_and1_and2(i1 %a, i1 %b, i1 %c) !prof !0 {
; CHECK-LABEL: @bools2_logical_commute0_and1_and2(
-; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]
+; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]], !prof [[PROF3]]
; CHECK-NEXT: ret i1 [[OR]]
;
%not = xor i1 %c, -1
%and1 = and i1 %c, %a
%and2 = and i1 %not, %b
- %or = select i1 %and1, i1 true, i1 %and2
+ %or = select i1 %and1, i1 true, i1 %and2, !prof !1
ret i1 %or
}
@@ -799,8 +799,11 @@ define <2 x i1> @not_logical_and2(i1 %b, <2 x i32> %a) {
!0 = !{!"function_entry_count", i64 1000}
!1 = !{!"branch_weights", i32 2, i32 3}
+!2 = !{!"branch_weights", i32 5, i32 7}
+!3 = !{!"branch_weights", i32 11, i32 13}
;.
; CHECK: [[META0:![0-9]+]] = !{!"function_entry_count", i64 1000}
; CHECK: [[PROF1]] = !{!"branch_weights", i32 2, i32 3}
; CHECK: [[PROF2]] = !{!"branch_weights", i32 3, i32 2}
+; CHECK: [[PROF3]] = !{!"unknown", !"instcombine"}
;.
diff --git a/llvm/utils/profcheck-xfail.txt b/llvm/utils/profcheck-xfail.txt
index 380b162d8c58c..661c88125c9c8 100644
--- a/llvm/utils/profcheck-xfail.txt
+++ b/llvm/utils/profcheck-xfail.txt
@@ -917,7 +917,6 @@ Transforms/InstCombine/select_frexp.ll
Transforms/InstCombine/select.ll
Transforms/InstCombine/select-min-max.ll
Transforms/InstCombine/select-of-symmetric-selects.ll
-Transforms/InstCombine/select-safe-transforms.ll
Transforms/InstCombine/select-select.ll
Transforms/InstCombine/select-with-extreme-eq-cond.ll
Transforms/InstCombine/shift.ll
More information about the llvm-commits
mailing list