@@ -3636,6 +3636,52 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
36363636 foldAddLikeCommutative (I.getOperand (1 ), I.getOperand (0 ),
36373637 /* NSW=*/ true , /* NUW=*/ true ))
36383638 return R;
3639+
3640+ Value *Cond0 = nullptr , *Cond1 = nullptr ;
3641+ const APInt *Op0Eq = nullptr , *Op0Ne = nullptr ;
3642+ const APInt *Op1Eq = nullptr , *Op1Ne = nullptr ;
3643+
3644+ // (!(A & N) ? 0 : N * C) + (!(A & M) ? 0 : M * C) -> A & (N + M) * C
3645+ if (match (I.getOperand (0 ),
3646+ m_Select (m_Value (Cond0), m_APInt (Op0Eq), m_APInt (Op0Ne))) &&
3647+ match (I.getOperand (1 ),
3648+ m_Select (m_Value (Cond1), m_APInt (Op1Eq), m_APInt (Op1Ne)))) {
3649+
3650+ auto LHSDecompose =
3651+ decomposeBitTest (Cond0, /* LookThruTrunc=*/ true ,
3652+ /* AllowNonZeroC=*/ false , /* DecomposeAnd=*/ true );
3653+ auto RHSDecompose =
3654+ decomposeBitTest (Cond1, /* LookThruTrunc=*/ true ,
3655+ /* AllowNonZeroC=*/ false , /* DecomposeAnd=*/ true );
3656+
3657+ if (LHSDecompose && RHSDecompose && LHSDecompose->X == RHSDecompose->X &&
3658+ RHSDecompose->Mask .isPowerOf2 () && LHSDecompose->Mask .isPowerOf2 () &&
3659+ LHSDecompose->Mask != RHSDecompose->Mask &&
3660+ LHSDecompose->Mask .getBitWidth () == Op0Ne->getBitWidth () &&
3661+ RHSDecompose->Mask .getBitWidth () == Op1Ne->getBitWidth ()) {
3662+ assert (Op0Ne->getBitWidth () == Op1Ne->getBitWidth ());
3663+ assert (ICmpInst::isEquality (LHSDecompose->Pred ));
3664+ if (LHSDecompose->Pred == ICmpInst::ICMP_NE)
3665+ std::swap (Op0Eq, Op0Ne);
3666+ if (RHSDecompose->Pred == ICmpInst::ICMP_NE)
3667+ std::swap (Op1Eq, Op1Ne);
3668+
3669+ if (!Op0Ne->isZero () && !Op1Ne->isZero () && Op0Eq->isZero () &&
3670+ Op1Eq->isZero () && Op0Ne->urem (LHSDecompose->Mask ).isZero () &&
3671+ Op1Ne->urem (RHSDecompose->Mask ).isZero () &&
3672+ Op0Ne->udiv (LHSDecompose->Mask ) ==
3673+ Op1Ne->udiv (RHSDecompose->Mask )) {
3674+ auto NewAnd = Builder.CreateAnd (
3675+ LHSDecompose->X ,
3676+ ConstantInt::get (LHSDecompose->X ->getType (),
3677+ (LHSDecompose->Mask + RHSDecompose->Mask )));
3678+
3679+ return BinaryOperator::CreateMul (
3680+ NewAnd, ConstantInt::get (NewAnd->getType (),
3681+ Op0Ne->udiv (LHSDecompose->Mask )));
3682+ }
3683+ }
3684+ }
36393685 }
36403686
36413687 Value *X, *Y;
0 commit comments