Skip to content

Commit fea9ef3

Browse files
authored
[InstCombine] Preserve profile branch weights when folding logical booleans (#161293)
Logical booleans in LLVM are represented by select statements - e.g. the statement ``` A && B ``` is represented as ``` select i1 %A, i1 %B, i1 false ``` When LLVM folds two of the same logical booleans into a logical boolean and a bitwise boolean (e.g. `A && B && C` -> `A && (B & C)`), the first logical boolean is a select statement that retains the original condition from the first logical boolean of the original statement. This means that the new select statement has the branch weights as the original select statement. Tracking issue: #147390
1 parent bf0a6ae commit fea9ef3

File tree

3 files changed

+33
-15
lines changed

3 files changed

+33
-15
lines changed

llvm/include/llvm/IR/IRBuilder.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1722,16 +1722,19 @@ class IRBuilderBase {
17221722
return Insert(BinOp, Name);
17231723
}
17241724

1725-
Value *CreateLogicalAnd(Value *Cond1, Value *Cond2, const Twine &Name = "") {
1725+
Value *CreateLogicalAnd(Value *Cond1, Value *Cond2, const Twine &Name = "",
1726+
Instruction *MDFrom = nullptr) {
17261727
assert(Cond2->getType()->isIntOrIntVectorTy(1));
17271728
return CreateSelect(Cond1, Cond2,
1728-
ConstantInt::getNullValue(Cond2->getType()), Name);
1729+
ConstantInt::getNullValue(Cond2->getType()), Name,
1730+
MDFrom);
17291731
}
17301732

1731-
Value *CreateLogicalOr(Value *Cond1, Value *Cond2, const Twine &Name = "") {
1733+
Value *CreateLogicalOr(Value *Cond1, Value *Cond2, const Twine &Name = "",
1734+
Instruction *MDFrom = nullptr) {
17321735
assert(Cond2->getType()->isIntOrIntVectorTy(1));
17331736
return CreateSelect(Cond1, ConstantInt::getAllOnesValue(Cond2->getType()),
1734-
Cond2, Name);
1737+
Cond2, Name, MDFrom);
17351738
}
17361739

17371740
Value *CreateLogicalOp(Instruction::BinaryOps Opc, Value *Cond1, Value *Cond2,

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3356,7 +3356,10 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {
33563356
impliesPoisonOrCond(FalseVal, B, /*Expected=*/false)) {
33573357
// (A || B) || C --> A || (B | C)
33583358
return replaceInstUsesWith(
3359-
SI, Builder.CreateLogicalOr(A, Builder.CreateOr(B, FalseVal)));
3359+
SI, Builder.CreateLogicalOr(A, Builder.CreateOr(B, FalseVal), "",
3360+
ProfcheckDisableMetadataFixes
3361+
? nullptr
3362+
: cast<SelectInst>(CondVal)));
33603363
}
33613364

33623365
// (A && B) || (C && B) --> (A || C) && B
@@ -3398,7 +3401,10 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {
33983401
impliesPoisonOrCond(TrueVal, B, /*Expected=*/true)) {
33993402
// (A && B) && C --> A && (B & C)
34003403
return replaceInstUsesWith(
3401-
SI, Builder.CreateLogicalAnd(A, Builder.CreateAnd(B, TrueVal)));
3404+
SI, Builder.CreateLogicalAnd(A, Builder.CreateAnd(B, TrueVal), "",
3405+
ProfcheckDisableMetadataFixes
3406+
? nullptr
3407+
: cast<SelectInst>(CondVal)));
34023408
}
34033409

34043410
// (A || B) && (C || B) --> (A && C) || B

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

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
22
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
33

44
; TODO: All of these should be optimized to less than or equal to a single
@@ -7,13 +7,13 @@
77
; --- (A op B) op' A / (B op A) op' A ---
88

99
; (A land B) land A
10-
define i1 @land_land_left1(i1 %A, i1 %B) {
10+
define i1 @land_land_left1(i1 %A, i1 %B) !prof !0 {
1111
; CHECK-LABEL: @land_land_left1(
12-
; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
12+
; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false, !prof [[PROF1:![0-9]+]]
1313
; CHECK-NEXT: ret i1 [[C]]
1414
;
15-
%c = select i1 %A, i1 %B, i1 false
16-
%res = select i1 %c, i1 %A, i1 false
15+
%c = select i1 %A, i1 %B, i1 false, !prof !1
16+
%res = select i1 %c, i1 %A, i1 false, !prof !2
1717
ret i1 %res
1818
}
1919
define i1 @land_land_left2(i1 %A, i1 %B) {
@@ -157,13 +157,13 @@ define i1 @lor_band_left2(i1 %A, i1 %B) {
157157
}
158158

159159
; (A lor B) lor A
160-
define i1 @lor_lor_left1(i1 %A, i1 %B) {
160+
define i1 @lor_lor_left1(i1 %A, i1 %B) !prof !0 {
161161
; CHECK-LABEL: @lor_lor_left1(
162-
; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
162+
; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]], !prof [[PROF1]]
163163
; CHECK-NEXT: ret i1 [[C]]
164164
;
165-
%c = select i1 %A, i1 true, i1 %B
166-
%res = select i1 %c, i1 true, i1 %A
165+
%c = select i1 %A, i1 true, i1 %B, !prof !1
166+
%res = select i1 %c, i1 true, i1 %A, !prof !2
167167
ret i1 %res
168168
}
169169
define i1 @lor_lor_left2(i1 %A, i1 %B) {
@@ -506,3 +506,12 @@ define <2 x i1> @PR50500_falseval(<2 x i1> %a, <2 x i1> %b) {
506506
%r = select <2 x i1> %a, <2 x i1> %b, <2 x i1> %s
507507
ret <2 x i1> %r
508508
}
509+
510+
!0 = !{!"function_entry_count", i64 1000}
511+
!1 = !{!"branch_weights", i32 2, i32 3}
512+
!2 = !{!"branch_weights", i32 5, i32 7}
513+
514+
;.
515+
; CHECK: [[META0:![0-9]+]] = !{!"function_entry_count", i64 1000}
516+
; CHECK: [[PROF1]] = !{!"branch_weights", i32 2, i32 3}
517+
;.

0 commit comments

Comments
 (0)