diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2947,6 +2947,16 @@ Constant::getNullValue(NewOr->getType())); } + // (icmp ne A, -1) | (icmp ne B, -1) --> (icmp ne (A&B), -1) + // (icmp eq A, -1) & (icmp eq B, -1) --> (icmp eq (A&B), -1) + if (!IsLogical && PredL == (IsAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE) && + PredL == PredR && match(LHS1, m_AllOnes()) && match(RHS1, m_AllOnes()) && + LHS0->getType() == RHS0->getType()) { + Value *NewAnd = Builder.CreateAnd(LHS0, RHS0); + return Builder.CreateICmp(PredL, NewAnd, + Constant::getAllOnesValue(LHS0->getType())); + } + // This only handles icmp of constants: (icmp1 A, C1) | (icmp2 B, C2). if (!LHSC || !RHSC) return nullptr;