diff options
author | Mircea Trofin <mtrofin@google.com> | 2025-09-12 07:50:44 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-09-12 07:50:44 -0700 |
commit | 889c289a409eea443cc5eba54d68cc6a3161be07 (patch) | |
tree | 264232df0c12267c47acc76d019deac019f3e8a1 /llvm/lib/Transforms/Utils/SimplifyCFG.cpp | |
parent | 179f01b800e29b38f7d97c043ff331d4f202a12a (diff) | |
download | llvm-889c289a409eea443cc5eba54d68cc6a3161be07.zip llvm-889c289a409eea443cc5eba54d68cc6a3161be07.tar.gz llvm-889c289a409eea443cc5eba54d68cc6a3161be07.tar.bz2 |
[SimplfyCFG] Set `MD_prof` for `select` used for certain conditional simplifications (#154426)
There’s a pattern where a branch is conditioned on a conjunction or disjunction that ends up being modeled as a `select` where the first operand is set to `true` or the second to `false`. If the branch has known branch weights, they can be copied to the `select`. This is worth doing in case later the `select` gets transformed to something else (i.e. if we know the profile, we should propagate it).
Issue #147390
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyCFG.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 850e57e..e551740 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -332,6 +332,16 @@ public: } }; +// we synthesize a || b as select a, true, b +// we synthesize a && b as select a, b, false +// this function determines if SI is playing one of those roles. +bool isSelectInRoleOfConjunctionOrDisjunction(const SelectInst *SI) { + return ((isa<ConstantInt>(SI->getTrueValue()) && + (dyn_cast<ConstantInt>(SI->getTrueValue())->isOne())) || + (isa<ConstantInt>(SI->getFalseValue()) && + (dyn_cast<ConstantInt>(SI->getFalseValue())->isNullValue()))); +} + } // end anonymous namespace /// Return true if all the PHI nodes in the basic block \p BB @@ -4033,6 +4043,7 @@ static bool performBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI, // Try to update branch weights. uint64_t PredTrueWeight, PredFalseWeight, SuccTrueWeight, SuccFalseWeight; + SmallVector<uint32_t, 2> MDWeights; if (extractPredSuccWeights(PBI, BI, PredTrueWeight, PredFalseWeight, SuccTrueWeight, SuccFalseWeight)) { SmallVector<uint64_t, 8> NewWeights; @@ -4063,7 +4074,7 @@ static bool performBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI, // Halve the weights if any of them cannot fit in an uint32_t fitWeights(NewWeights); - SmallVector<uint32_t, 8> MDWeights(NewWeights.begin(), NewWeights.end()); + append_range(MDWeights, NewWeights); setBranchWeights(PBI, MDWeights[0], MDWeights[1], /*IsExpected=*/false); // TODO: If BB is reachable from all paths through PredBlock, then we @@ -4100,6 +4111,13 @@ static bool performBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI, Value *BICond = VMap[BI->getCondition()]; PBI->setCondition( createLogicalOp(Builder, Opc, PBI->getCondition(), BICond, "or.cond")); + if (!ProfcheckDisableMetadataFixes) + if (auto *SI = dyn_cast<SelectInst>(PBI->getCondition())) + if (!MDWeights.empty()) { + assert(isSelectInRoleOfConjunctionOrDisjunction(SI)); + setBranchWeights(SI, MDWeights[0], MDWeights[1], + /*IsExpected=*/false); + } ++NumFoldBranchToCommonDest; return true; @@ -4812,6 +4830,18 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI, fitWeights(NewWeights); setBranchWeights(PBI, NewWeights[0], NewWeights[1], /*IsExpected=*/false); + // Cond may be a select instruction with the first operand set to "true", or + // the second to "false" (see how createLogicalOp works for `and` and `or`) + if (!ProfcheckDisableMetadataFixes) + if (auto *SI = dyn_cast<SelectInst>(Cond)) { + assert(isSelectInRoleOfConjunctionOrDisjunction(SI)); + // The select is predicated on PBICond + assert(dyn_cast<SelectInst>(SI)->getCondition() == PBICond); + // The corresponding probabilities are what was referred to above as + // PredCommon and PredOther. + setBranchWeights(SI, PredCommon, PredOther, + /*IsExpected=*/false); + } } // OtherDest may have phi nodes. If so, add an entry from PBI's |