@@ -701,6 +701,42 @@ 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
+ // We could potentially be more sophisticated than requiring LHS/RHS be
727
+ // one-use. We don't create additional instructions if only one of them is
728
+ // one-use. So cases where one is one-use and the other is two-use might be
729
+ // profitable.
730
+ if (!match (LHS, m_OneUse (m_ICmp (Pred, m_Value (Op), m_Zero ()))) ||
731
+ !match (RHS, m_OneUse (m_c_ICmp (Pred, m_Specific (Op), m_Value (Pow2)))) ||
732
+ !isKnownToBeAPowerOfTwo (Pow2, Q.DL , /* OrZero=*/ true , /* Depth=*/ 0 , Q.AC ,
733
+ Q.CxtI , Q.DT ))
734
+ return nullptr ;
735
+
736
+ Value *And = Builder.CreateAnd (Op, Pow2);
737
+ return Builder.CreateICmp (Pred, And, Op);
738
+ }
739
+
704
740
// Fold (iszero(A & K1) | iszero(A & K2)) -> (A & (K1 | K2)) != (K1 | K2)
705
741
// Fold (!iszero(A & K1) & !iszero(A & K2)) -> (A & (K1 | K2)) == (K1 | K2)
706
742
Value *InstCombinerImpl::foldAndOrOfICmpsOfAndWithPow2 (ICmpInst *LHS,
@@ -3240,6 +3276,11 @@ Value *InstCombinerImpl::foldAndOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
3240
3276
ICmpInst::Predicate PredL = LHS->getPredicate (), PredR = RHS->getPredicate ();
3241
3277
Value *LHS0 = LHS->getOperand (0 ), *RHS0 = RHS->getOperand (0 );
3242
3278
Value *LHS1 = LHS->getOperand (1 ), *RHS1 = RHS->getOperand (1 );
3279
+ if (!IsLogical)
3280
+ if (Value *V =
3281
+ foldAndOrOfICmpsWithPow2AndWithZero (Builder, LHS, RHS, IsAnd, Q))
3282
+ return V;
3283
+
3243
3284
const APInt *LHSC = nullptr , *RHSC = nullptr ;
3244
3285
match (LHS1, m_APInt (LHSC));
3245
3286
match (RHS1, m_APInt (RHSC));
0 commit comments