[llvm] [InstCombine] Fold `(icmp eq/ne (or (select cond, 0/NZ, 0/NZ), X), 0)` (PR #88183)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 3 08:16:28 PDT 2024
================
@@ -3491,6 +3491,57 @@ Instruction *InstCombinerImpl::foldICmpBinOpEqualityWithConstant(
Value *And = Builder.CreateAnd(BOp0, NotBOC);
return new ICmpInst(Pred, And, NotBOC);
}
+ // (icmp eq (or (select cond, 0, NonZero), Other), 0)
+ // -> (and cond, (icmp eq Other, 0))
+ // (icmp ne (or (select cond, NonZero, 0), Other), 0)
+ // -> (or cond, (icmp ne Other, 0))
+ Value *Cond, *TV, *FV, *Other;
+ if (C.isZero() &&
+ match(BO,
+ m_OneUse(m_c_Or(m_Select(m_Value(Cond), m_Value(TV), m_Value(FV)),
+ m_Value(Other))))) {
+ const SimplifyQuery Q = SQ.getWithInstruction(&Cmp);
+ // Easy case is if eq/ne matches whether 0 is trueval/falseval.
+ if (Pred == ICmpInst::ICMP_EQ
+ ? (match(TV, m_SpecificInt(C)) && isKnownNonZero(FV, Q))
+ : (match(FV, m_SpecificInt(C)) && isKnownNonZero(TV, Q))) {
+ Value *Cmp = Builder.CreateICmp(
+ Pred, Other, Constant::getNullValue(Other->getType()));
+ return BinaryOperator::Create(
+ Pred == ICmpInst::ICMP_EQ ? Instruction::And : Instruction::Or, Cmp,
+ Cond);
+ }
+ // Harder case is if eq/ne matches whether 0 is falseval/trueval. In this
+ // case we need to invert the select condition so we need to be careful to
+ // avoid creating extra instructions.
+ // (icmp ne (or (select cond, 0, NonZero), Other), 0)
+ // -> (or (not cond), (icmp ne Other, 0))
+ // (icmp eq (or (select cond, NonZero, 0), Other), 0)
+ // -> (and (not cond), (icmp eq Other, 0))
+ if (Pred == ICmpInst::ICMP_EQ
+ ? (match(FV, m_SpecificInt(C)) && isKnownNonZero(TV, Q))
+ : (match(TV, m_SpecificInt(C)) && isKnownNonZero(FV, Q))) {
+ Value *NotCond = nullptr;
+ // If the select is one use, we are essentially replacing select with
+ // `(not Cond)`.
+ auto SelectMatcher =
+ m_Select(m_Specific(Cond), m_Specific(TV), m_Specific(FV));
+ if (match(BO, m_c_Or(m_OneUse(SelectMatcher), m_Value())))
----------------
dtcxzyw wrote:
Use `SelInst` to avoid matching twice.
https://github.com/llvm/llvm-project/pull/88183
More information about the llvm-commits
mailing list