[llvm] [X86] Don't always seperate conditions in `(br (and/or cond0, cond1))` into seperate branches (PR #81689)
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 14 02:29:22 PST 2024
================
@@ -3339,6 +3361,143 @@ unsigned X86TargetLowering::preferedOpcodeForCmpEqPiecesOfOperand(
return ISD::SRL;
}
+// Collect dependings on V recursively. This is used for the cost analysis in
+// `keepJumpConditionsTogether`.
+static bool
+collectDeps(SmallPtrSet<const Instruction *, 8> *Deps, const Value *V,
+ SmallPtrSet<const Instruction *, 8> *Necessary = nullptr,
+ unsigned Depth = 0) {
+ // Return false if we have an incomplete count.
+ if (Depth >= 6)
+ return false;
+
+ auto *I = dyn_cast<Instruction>(V);
+ if (I == nullptr)
+ return true;
+
+ if (Necessary != nullptr) {
+ // This instruction is necessary for the other side of the condition so
+ // don't count it.
+ if (Necessary->contains(I))
+ return true;
+ }
+
+ // Already added this dep.
+ if (!Deps->insert(I).second)
+ return true;
+
+ for (unsigned OpIdx = 0; OpIdx < I->getNumOperands(); ++OpIdx)
+ if (!collectDeps(Deps, I->getOperand(OpIdx), Necessary, Depth + 1))
+ return false;
+ return true;
+}
+
+bool X86TargetLowering::keepJumpConditionsTogether(
+ const FunctionLoweringInfo &FuncInfo, const BranchInst &I,
+ Instruction::BinaryOps Opc, const Value *Lhs, const Value *Rhs) const {
+ using namespace llvm::PatternMatch;
+ if (I.getNumSuccessors() != 2)
+ return false;
+
+ // Baseline cost. This is properly arbitrary.
+ InstructionCost CostThresh = BrMergingBaseCostThresh.getValue();
+ if (BrMergingBaseCostThresh.getValue() < 0)
+ return false;
+
+ // a == b && c == d can be efficiently combined.
+ ICmpInst::Predicate Pred;
+ if (Opc == Instruction::And &&
+ match(Lhs, m_ICmp(Pred, m_Value(), m_Value())) &&
+ Pred == ICmpInst::ICMP_EQ &&
+ match(Rhs, m_ICmp(Pred, m_Value(), m_Value())) &&
+ Pred == ICmpInst::ICMP_EQ)
+ CostThresh += 1;
+
+ BranchProbabilityInfo *BPI = nullptr;
+ if (BrMergingLikelyBias.getValue() || BrMergingUnlikelyBias.getValue())
+ BPI = FuncInfo.BPI;
+ if (BPI != nullptr) {
+ BasicBlock *IfFalse = I.getSuccessor(0);
+ BasicBlock *IfTrue = I.getSuccessor(1);
+
+ std::optional<bool> Likely;
+ if (BPI->isEdgeHot(I.getParent(), IfTrue))
+ Likely = true;
+ else if (BPI->isEdgeHot(I.getParent(), IfFalse))
+ Likely = false;
+
+ if (Likely) {
+ if (Opc == (*Likely ? Instruction::And : Instruction::Or))
+ // Its likely we will have to compute both lhs and rhs of condition
+ CostThresh += BrMergingLikelyBias.getValue();
+ else {
+ // Its likely we will get an early out.
+ CostThresh -= BrMergingUnlikelyBias.getValue();
+ if (BrMergingUnlikelyBias.getValue() < 0) {
----------------
RKSimon wrote:
Attempt this earlier?
https://github.com/llvm/llvm-project/pull/81689
More information about the llvm-commits
mailing list