Skip to content

Commit 0bc1ec5

Browse files
authored
[GlobalISel] Reduce KnownBits usage in matcher combines (#92381)
Two icmp/and combines forced computation of KnownBits on all operands everytime. We can avoid computing KnownBits on the LHS by exploiting a couple of properties: - Constants are always on the RHS for those instructions. If we have no KnownBits on the RHS, we can bail out early and avoid computing LHS knownbits. - For icmp uge/ult 0, we don't need to know the KBs of the LHS to infer the result This allows to save some KnownBits calls, which are very expensive, without affecting codegen.
1 parent 46bc54f commit 0bc1ec5

File tree

1 file changed

+67
-35
lines changed

1 file changed

+67
-35
lines changed

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

+67-35
Original file line numberDiff line numberDiff line change
@@ -3220,8 +3220,15 @@ bool CombinerHelper::matchRedundantAnd(MachineInstr &MI,
32203220
Register AndDst = MI.getOperand(0).getReg();
32213221
Register LHS = MI.getOperand(1).getReg();
32223222
Register RHS = MI.getOperand(2).getReg();
3223-
KnownBits LHSBits = KB->getKnownBits(LHS);
3223+
3224+
// Check the RHS (maybe a constant) first, and if we have no KnownBits there,
3225+
// we can't do anything. If we do, then it depends on whether we have
3226+
// KnownBits on the LHS.
32243227
KnownBits RHSBits = KB->getKnownBits(RHS);
3228+
if (RHSBits.isUnknown())
3229+
return false;
3230+
3231+
KnownBits LHSBits = KB->getKnownBits(LHS);
32253232

32263233
// Check that x & Mask == x.
32273234
// x & 1 == x, always
@@ -3260,6 +3267,7 @@ bool CombinerHelper::matchRedundantOr(MachineInstr &MI, Register &Replacement) {
32603267
Register OrDst = MI.getOperand(0).getReg();
32613268
Register LHS = MI.getOperand(1).getReg();
32623269
Register RHS = MI.getOperand(2).getReg();
3270+
32633271
KnownBits LHSBits = KB->getKnownBits(LHS);
32643272
KnownBits RHSBits = KB->getKnownBits(RHS);
32653273

@@ -4253,43 +4261,67 @@ bool CombinerHelper::matchICmpToTrueFalseKnownBits(MachineInstr &MI,
42534261
int64_t &MatchInfo) {
42544262
assert(MI.getOpcode() == TargetOpcode::G_ICMP);
42554263
auto Pred = static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
4256-
auto KnownLHS = KB->getKnownBits(MI.getOperand(2).getReg());
4264+
4265+
// We want to avoid calling KnownBits on the LHS if possible, as this combine
4266+
// has no filter and runs on every G_ICMP instruction. We can avoid calling
4267+
// KnownBits on the LHS in two cases:
4268+
//
4269+
// - The RHS is unknown: Constants are always on RHS. If the RHS is unknown
4270+
// we cannot do any transforms so we can safely bail out early.
4271+
// - The RHS is zero: we don't need to know the LHS to do unsigned <0 and
4272+
// >=0.
42574273
auto KnownRHS = KB->getKnownBits(MI.getOperand(3).getReg());
4274+
if (KnownRHS.isUnknown())
4275+
return false;
4276+
42584277
std::optional<bool> KnownVal;
4259-
switch (Pred) {
4260-
default:
4261-
llvm_unreachable("Unexpected G_ICMP predicate?");
4262-
case CmpInst::ICMP_EQ:
4263-
KnownVal = KnownBits::eq(KnownLHS, KnownRHS);
4264-
break;
4265-
case CmpInst::ICMP_NE:
4266-
KnownVal = KnownBits::ne(KnownLHS, KnownRHS);
4267-
break;
4268-
case CmpInst::ICMP_SGE:
4269-
KnownVal = KnownBits::sge(KnownLHS, KnownRHS);
4270-
break;
4271-
case CmpInst::ICMP_SGT:
4272-
KnownVal = KnownBits::sgt(KnownLHS, KnownRHS);
4273-
break;
4274-
case CmpInst::ICMP_SLE:
4275-
KnownVal = KnownBits::sle(KnownLHS, KnownRHS);
4276-
break;
4277-
case CmpInst::ICMP_SLT:
4278-
KnownVal = KnownBits::slt(KnownLHS, KnownRHS);
4279-
break;
4280-
case CmpInst::ICMP_UGE:
4281-
KnownVal = KnownBits::uge(KnownLHS, KnownRHS);
4282-
break;
4283-
case CmpInst::ICMP_UGT:
4284-
KnownVal = KnownBits::ugt(KnownLHS, KnownRHS);
4285-
break;
4286-
case CmpInst::ICMP_ULE:
4287-
KnownVal = KnownBits::ule(KnownLHS, KnownRHS);
4288-
break;
4289-
case CmpInst::ICMP_ULT:
4290-
KnownVal = KnownBits::ult(KnownLHS, KnownRHS);
4291-
break;
4278+
if (KnownRHS.isZero()) {
4279+
// ? uge 0 -> always true
4280+
// ? ult 0 -> always false
4281+
if (Pred == CmpInst::ICMP_UGE)
4282+
KnownVal = true;
4283+
else if (Pred == CmpInst::ICMP_ULT)
4284+
KnownVal = false;
42924285
}
4286+
4287+
if (!KnownVal) {
4288+
auto KnownLHS = KB->getKnownBits(MI.getOperand(2).getReg());
4289+
switch (Pred) {
4290+
default:
4291+
llvm_unreachable("Unexpected G_ICMP predicate?");
4292+
case CmpInst::ICMP_EQ:
4293+
KnownVal = KnownBits::eq(KnownLHS, KnownRHS);
4294+
break;
4295+
case CmpInst::ICMP_NE:
4296+
KnownVal = KnownBits::ne(KnownLHS, KnownRHS);
4297+
break;
4298+
case CmpInst::ICMP_SGE:
4299+
KnownVal = KnownBits::sge(KnownLHS, KnownRHS);
4300+
break;
4301+
case CmpInst::ICMP_SGT:
4302+
KnownVal = KnownBits::sgt(KnownLHS, KnownRHS);
4303+
break;
4304+
case CmpInst::ICMP_SLE:
4305+
KnownVal = KnownBits::sle(KnownLHS, KnownRHS);
4306+
break;
4307+
case CmpInst::ICMP_SLT:
4308+
KnownVal = KnownBits::slt(KnownLHS, KnownRHS);
4309+
break;
4310+
case CmpInst::ICMP_UGE:
4311+
KnownVal = KnownBits::uge(KnownLHS, KnownRHS);
4312+
break;
4313+
case CmpInst::ICMP_UGT:
4314+
KnownVal = KnownBits::ugt(KnownLHS, KnownRHS);
4315+
break;
4316+
case CmpInst::ICMP_ULE:
4317+
KnownVal = KnownBits::ule(KnownLHS, KnownRHS);
4318+
break;
4319+
case CmpInst::ICMP_ULT:
4320+
KnownVal = KnownBits::ult(KnownLHS, KnownRHS);
4321+
break;
4322+
}
4323+
}
4324+
42934325
if (!KnownVal)
42944326
return false;
42954327
MatchInfo =

0 commit comments

Comments
 (0)