Skip to content

Commit c4763e2

Browse files
authored
[profcheck][InstCombine] Preserve branch weights in logical identities (llvm#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: llvm#147390
1 parent 513334f commit c4763e2

File tree

3 files changed

+56
-25
lines changed

3 files changed

+56
-25
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3599,6 +3599,21 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {
35993599
m_Not(m_Specific(SelCond->getTrueValue())));
36003600
if (MayNeedFreeze)
36013601
C = Builder.CreateFreeze(C);
3602+
if (!ProfcheckDisableMetadataFixes) {
3603+
Value *C2 = nullptr, *A2 = nullptr, *B2 = nullptr;
3604+
if (match(CondVal, m_LogicalAnd(m_Specific(C), m_Value(A2))) &&
3605+
SelCond) {
3606+
return SelectInst::Create(C, A, B, "", nullptr, SelCond);
3607+
} else if (match(FalseVal,
3608+
m_LogicalAnd(m_Not(m_Value(C2)), m_Value(B2))) &&
3609+
SelFVal) {
3610+
SelectInst *NewSI = SelectInst::Create(C, A, B, "", nullptr, SelFVal);
3611+
NewSI->swapProfMetadata();
3612+
return NewSI;
3613+
} else {
3614+
return createSelectInstWithUnknownProfile(C, A, B);
3615+
}
3616+
}
36023617
return SelectInst::Create(C, A, B);
36033618
}
36043619

@@ -3615,6 +3630,20 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {
36153630
m_Not(m_Specific(SelFVal->getTrueValue())));
36163631
if (MayNeedFreeze)
36173632
C = Builder.CreateFreeze(C);
3633+
if (!ProfcheckDisableMetadataFixes) {
3634+
Value *C2 = nullptr, *A2 = nullptr, *B2 = nullptr;
3635+
if (match(CondVal, m_LogicalAnd(m_Not(m_Value(C2)), m_Value(A2))) &&
3636+
SelCond) {
3637+
SelectInst *NewSI = SelectInst::Create(C, B, A, "", nullptr, SelCond);
3638+
NewSI->swapProfMetadata();
3639+
return NewSI;
3640+
} else if (match(FalseVal, m_LogicalAnd(m_Specific(C), m_Value(B2))) &&
3641+
SelFVal) {
3642+
return SelectInst::Create(C, B, A, "", nullptr, SelFVal);
3643+
} else {
3644+
return createSelectInstWithUnknownProfile(C, B, A);
3645+
}
3646+
}
36183647
return SelectInst::Create(C, B, A);
36193648
}
36203649
}

llvm/test/Transforms/InstCombine/select-safe-transforms.ll

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -256,27 +256,27 @@ define <2 x i1> @not_logical_or2(i1 %b, <2 x i32> %a) {
256256
ret <2 x i1> %and
257257
}
258258

259-
define i1 @bools_logical_commute0(i1 %a, i1 %b, i1 %c) {
259+
define i1 @bools_logical_commute0(i1 %a, i1 %b, i1 %c) !prof !0 {
260260
; CHECK-LABEL: @bools_logical_commute0(
261-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]
261+
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]], !prof [[PROF2]]
262262
; CHECK-NEXT: ret i1 [[OR]]
263263
;
264264
%not = xor i1 %c, -1
265-
%and1 = select i1 %not, i1 %a, i1 false
266-
%and2 = select i1 %c, i1 %b, i1 false
267-
%or = select i1 %and1, i1 true, i1 %and2
265+
%and1 = select i1 %not, i1 %a, i1 false, !prof!1
266+
%and2 = select i1 %c, i1 %b, i1 false, !prof !2
267+
%or = select i1 %and1, i1 true, i1 %and2, !prof !3
268268
ret i1 %or
269269
}
270270

271-
define i1 @bools_logical_commute0_and1(i1 %a, i1 %b, i1 %c) {
271+
define i1 @bools_logical_commute0_and1(i1 %a, i1 %b, i1 %c) !prof !0 {
272272
; CHECK-LABEL: @bools_logical_commute0_and1(
273-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]
273+
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]], !prof [[PROF1]]
274274
; CHECK-NEXT: ret i1 [[OR]]
275275
;
276276
%not = xor i1 %c, -1
277277
%and1 = and i1 %not, %a
278-
%and2 = select i1 %c, i1 %b, i1 false
279-
%or = select i1 %and1, i1 true, i1 %and2
278+
%and2 = select i1 %c, i1 %b, i1 false, !prof !1
279+
%or = select i1 %and1, i1 true, i1 %and2, !prof !2
280280
ret i1 %or
281281
}
282282

@@ -292,15 +292,15 @@ define i1 @bools_logical_commute0_and2(i1 %a, i1 %b, i1 %c) {
292292
ret i1 %or
293293
}
294294

295-
define i1 @bools_logical_commute0_and1_and2(i1 %a, i1 %b, i1 %c) {
295+
define i1 @bools_logical_commute0_and1_and2(i1 %a, i1 %b, i1 %c) !prof !0 {
296296
; CHECK-LABEL: @bools_logical_commute0_and1_and2(
297-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]
297+
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]], !prof [[PROF3:![0-9]+]]
298298
; CHECK-NEXT: ret i1 [[OR]]
299299
;
300300
%not = xor i1 %c, -1
301301
%and1 = and i1 %not, %a
302302
%and2 = and i1 %c, %b
303-
%or = select i1 %and1, i1 true, i1 %and2
303+
%or = select i1 %and1, i1 true, i1 %and2, !prof !1
304304
ret i1 %or
305305
}
306306

@@ -457,27 +457,27 @@ define i1 @bools_logical_commute3_and1_and2(i1 %b, i1 %c) {
457457
ret i1 %or
458458
}
459459

460-
define i1 @bools2_logical_commute0(i1 %a, i1 %b, i1 %c) {
460+
define i1 @bools2_logical_commute0(i1 %a, i1 %b, i1 %c) !prof !0 {
461461
; CHECK-LABEL: @bools2_logical_commute0(
462-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]
462+
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]], !prof [[PROF1]]
463463
; CHECK-NEXT: ret i1 [[OR]]
464464
;
465465
%not = xor i1 %c, -1
466-
%and1 = select i1 %c, i1 %a, i1 false
467-
%and2 = select i1 %not, i1 %b, i1 false
468-
%or = select i1 %and1, i1 true, i1 %and2
466+
%and1 = select i1 %c, i1 %a, i1 false, !prof !1
467+
%and2 = select i1 %not, i1 %b, i1 false, !prof !2
468+
%or = select i1 %and1, i1 true, i1 %and2, !prof !3
469469
ret i1 %or
470470
}
471471

472-
define i1 @bools2_logical_commute0_and1(i1 %a, i1 %b, i1 %c) {
472+
define i1 @bools2_logical_commute0_and1(i1 %a, i1 %b, i1 %c) !prof !0 {
473473
; CHECK-LABEL: @bools2_logical_commute0_and1(
474-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]
474+
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]], !prof [[PROF2]]
475475
; CHECK-NEXT: ret i1 [[OR]]
476476
;
477477
%not = xor i1 %c, -1
478478
%and1 = and i1 %c, %a
479-
%and2 = select i1 %not, i1 %b, i1 false
480-
%or = select i1 %and1, i1 true, i1 %and2
479+
%and2 = select i1 %not, i1 %b, i1 false, !prof !1
480+
%or = select i1 %and1, i1 true, i1 %and2, !prof !2
481481
ret i1 %or
482482
}
483483

@@ -493,15 +493,15 @@ define i1 @bools2_logical_commute0_and2(i1 %a, i1 %b, i1 %c) {
493493
ret i1 %or
494494
}
495495

496-
define i1 @bools2_logical_commute0_and1_and2(i1 %a, i1 %b, i1 %c) {
496+
define i1 @bools2_logical_commute0_and1_and2(i1 %a, i1 %b, i1 %c) !prof !0 {
497497
; CHECK-LABEL: @bools2_logical_commute0_and1_and2(
498-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]
498+
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]], !prof [[PROF3]]
499499
; CHECK-NEXT: ret i1 [[OR]]
500500
;
501501
%not = xor i1 %c, -1
502502
%and1 = and i1 %c, %a
503503
%and2 = and i1 %not, %b
504-
%or = select i1 %and1, i1 true, i1 %and2
504+
%or = select i1 %and1, i1 true, i1 %and2, !prof !1
505505
ret i1 %or
506506
}
507507

@@ -799,8 +799,11 @@ define <2 x i1> @not_logical_and2(i1 %b, <2 x i32> %a) {
799799

800800
!0 = !{!"function_entry_count", i64 1000}
801801
!1 = !{!"branch_weights", i32 2, i32 3}
802+
!2 = !{!"branch_weights", i32 5, i32 7}
803+
!3 = !{!"branch_weights", i32 11, i32 13}
802804
;.
803805
; CHECK: [[META0:![0-9]+]] = !{!"function_entry_count", i64 1000}
804806
; CHECK: [[PROF1]] = !{!"branch_weights", i32 2, i32 3}
805807
; CHECK: [[PROF2]] = !{!"branch_weights", i32 3, i32 2}
808+
; CHECK: [[PROF3]] = !{!"unknown", !"instcombine"}
806809
;.

llvm/utils/profcheck-xfail.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,6 @@ Transforms/InstCombine/select_frexp.ll
917917
Transforms/InstCombine/select.ll
918918
Transforms/InstCombine/select-min-max.ll
919919
Transforms/InstCombine/select-of-symmetric-selects.ll
920-
Transforms/InstCombine/select-safe-transforms.ll
921920
Transforms/InstCombine/select-select.ll
922921
Transforms/InstCombine/select-with-extreme-eq-cond.ll
923922
Transforms/InstCombine/shift.ll

0 commit comments

Comments
 (0)