Skip to content

Commit 64ebd5d

Browse files
committed
[InstCombine] Preserve profile branch weights when folding logical booleans
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 d23f781 commit 64ebd5d

File tree

3 files changed

+172
-152
lines changed

3 files changed

+172
-152
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: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
using namespace llvm;
5151
using namespace PatternMatch;
5252

53+
extern cl::opt<bool> ProfcheckDisableMetadataFixes;
5354

5455
/// Replace a select operand based on an equality comparison with the identity
5556
/// constant of a binop.
@@ -3369,7 +3370,10 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {
33693370
impliesPoisonOrCond(FalseVal, B, /*Expected=*/false)) {
33703371
// (A || B) || C --> A || (B | C)
33713372
return replaceInstUsesWith(
3372-
SI, Builder.CreateLogicalOr(A, Builder.CreateOr(B, FalseVal)));
3373+
SI, Builder.CreateLogicalOr(A, Builder.CreateOr(B, FalseVal), "",
3374+
ProfcheckDisableMetadataFixes
3375+
? nullptr
3376+
: cast<SelectInst>(CondVal)));
33733377
}
33743378

33753379
// (A && B) || (C && B) --> (A || C) && B
@@ -3411,7 +3415,10 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {
34113415
impliesPoisonOrCond(TrueVal, B, /*Expected=*/true)) {
34123416
// (A && B) && C --> A && (B & C)
34133417
return replaceInstUsesWith(
3414-
SI, Builder.CreateLogicalAnd(A, Builder.CreateAnd(B, TrueVal)));
3418+
SI, Builder.CreateLogicalAnd(A, Builder.CreateAnd(B, TrueVal), "",
3419+
ProfcheckDisableMetadataFixes
3420+
? nullptr
3421+
: cast<SelectInst>(CondVal)));
34153422
}
34163423

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

0 commit comments

Comments
 (0)