-
Notifications
You must be signed in to change notification settings - Fork 15k
[profcheck][InstCombine] Preserve branch weights in logical identities #165810
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[profcheck][InstCombine] Preserve branch weights in logical identities #165810
Conversation
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: llvm#147390
|
@llvm/pr-subscribers-llvm-transforms Author: Alan Zhao (alanzhao1) ChangesFor the simplification (and related), if If Furthermore, Tracking issue: #147390 Full diff: https://github.com/llvm/llvm-project/pull/165810.diff 3 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index f5130da818746..fb7de01bf254d 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, *A2, *B2;
+ if (match(CondVal, m_LogicalAnd(m_Specific(C2), 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, *A2, *B2;
+ if (match(CondVal, m_LogicalAnd(m_Not(m_Value(C2)), m_Value(B2))) &&
+ SelCond) {
+ SelectInst *NewSI = SelectInst::Create(C, B, A, "", nullptr, SelCond);
+ NewSI->swapProfMetadata();
+ return NewSI;
+ } else if (match(FalseVal, m_LogicalAnd(m_Specific(C2), m_Value(A2))) &&
+ 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..4299b63870294 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 [[PROF4:![0-9]+]]
; 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,12 @@ 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 17}
;.
; 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"}
+; CHECK: [[PROF4]] = !{!"branch_weights", i32 7, i32 5}
;.
diff --git a/llvm/utils/profcheck-xfail.txt b/llvm/utils/profcheck-xfail.txt
index aef7c0987fda7..b6589ce454394 100644
--- a/llvm/utils/profcheck-xfail.txt
+++ b/llvm/utils/profcheck-xfail.txt
@@ -913,7 +913,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
|
|
CI failure is due to an lldb test that seems unrelated. |
For the simplification
(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
Cis 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.iinow passes under the profcheck configuration, so we remove it from the failing tests.Tracking issue: #147390