@@ -701,6 +701,38 @@ Value *InstCombinerImpl::simplifyRangeCheck(ICmpInst *Cmp0, ICmpInst *Cmp1,
701
701
return Builder.CreateICmp (NewPred, Input, RangeEnd);
702
702
}
703
703
704
+ // (or (icmp eq X, 0), (icmp eq X, Pow2OrZero))
705
+ // -> (icmp eq (and X, Pow2OrZero), X)
706
+ // (and (icmp ne X, 0), (icmp ne X, Pow2OrZero))
707
+ // -> (icmp ne (and X, Pow2OrZero), X)
708
+ static Value *
709
+ foldAndOrOfICmpsWithPow2AndWithZero (InstCombiner::BuilderTy &Builder,
710
+ ICmpInst *LHS, ICmpInst *RHS, bool IsAnd,
711
+ const SimplifyQuery &Q) {
712
+ CmpInst::Predicate Pred = IsAnd ? CmpInst::ICMP_NE : CmpInst::ICMP_EQ;
713
+ // Make sure we have right compares for our op.
714
+ if (LHS->getPredicate () != Pred || RHS->getPredicate () != Pred)
715
+ return nullptr ;
716
+
717
+ // Make it so we can match LHS against the (icmp eq/ne X, 0) just for
718
+ // simplicity.
719
+ if (match (RHS->getOperand (1 ), m_Zero ()))
720
+ std::swap (LHS, RHS);
721
+
722
+ Value *Pow2, *Op;
723
+ // Match the desired pattern:
724
+ // LHS: (icmp eq/ne X, 0)
725
+ // RHS: (icmp eq/ne X, Pow2OrZero)
726
+ if (!match (LHS, m_ICmp (Pred, m_Value (Op), m_Zero ())) ||
727
+ !match (RHS, m_c_ICmp (Pred, m_Specific (Op), m_Value (Pow2))) ||
728
+ !isKnownToBeAPowerOfTwo (Pow2, Q.DL , /* OrZero*/ true , /* Depth*/ 0 , Q.AC ,
729
+ Q.CxtI , Q.DT ))
730
+ return nullptr ;
731
+
732
+ Value *And = Builder.CreateAnd (Op, Pow2);
733
+ return Builder.CreateICmp (Pred, And, Op);
734
+ }
735
+
704
736
// Fold (iszero(A & K1) | iszero(A & K2)) -> (A & (K1 | K2)) != (K1 | K2)
705
737
// Fold (!iszero(A & K1) & !iszero(A & K2)) -> (A & (K1 | K2)) == (K1 | K2)
706
738
Value *InstCombinerImpl::foldAndOrOfICmpsOfAndWithPow2 (ICmpInst *LHS,
@@ -3240,6 +3272,11 @@ Value *InstCombinerImpl::foldAndOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
3240
3272
ICmpInst::Predicate PredL = LHS->getPredicate (), PredR = RHS->getPredicate ();
3241
3273
Value *LHS0 = LHS->getOperand (0 ), *RHS0 = RHS->getOperand (0 );
3242
3274
Value *LHS1 = LHS->getOperand (1 ), *RHS1 = RHS->getOperand (1 );
3275
+ if (!IsLogical)
3276
+ if (Value *V =
3277
+ foldAndOrOfICmpsWithPow2AndWithZero (Builder, LHS, RHS, IsAnd, Q))
3278
+ return V;
3279
+
3243
3280
const APInt *LHSC = nullptr , *RHSC = nullptr ;
3244
3281
match (LHS1, m_APInt (LHSC));
3245
3282
match (RHS1, m_APInt (RHSC));
0 commit comments