@@ -3664,32 +3664,35 @@ static std::optional<DecomposedBitMaskMul> matchBitmaskMul(Value *V) {
36643664 return std::nullopt ;
36653665}
36663666
3667- using CombinedBitmaskMul =
3668- std::pair<std::optional<DecomposedBitMaskMul>, Value *>;
3667+ struct CombinedBitmaskMul {
3668+ std::optional<DecomposedBitMaskMul> Decomp = std::nullopt ;
3669+ Value *DecompOp = nullptr ;
3670+ Value *OtherOp = nullptr ;
3671+ };
36693672
36703673static CombinedBitmaskMul matchCombinedBitmaskMul (Value *V) {
36713674 auto DecompBitMaskMul = matchBitmaskMul (V);
36723675 if (DecompBitMaskMul)
3673- return {DecompBitMaskMul, nullptr };
3676+ return {DecompBitMaskMul, V, nullptr };
36743677
36753678 // Otherwise, check the operands of V for bitmaskmul pattern
36763679 auto BOp = dyn_cast<BinaryOperator>(V);
36773680 if (!BOp)
3678- return {std:: nullopt , nullptr } ;
3681+ return CombinedBitmaskMul () ;
36793682
36803683 auto Disj = dyn_cast<PossiblyDisjointInst>(BOp);
36813684 if (!Disj || !Disj->isDisjoint ())
3682- return {std:: nullopt , nullptr } ;
3685+ return CombinedBitmaskMul () ;
36833686
36843687 auto DecompBitMaskMul0 = matchBitmaskMul (BOp->getOperand (0 ));
36853688 if (DecompBitMaskMul0)
3686- return {DecompBitMaskMul0, BOp->getOperand (1 )};
3689+ return {DecompBitMaskMul0, BOp->getOperand (0 ), BOp-> getOperand ( 1 )};
36873690
36883691 auto DecompBitMaskMul1 = matchBitmaskMul (BOp->getOperand (1 ));
36893692 if (DecompBitMaskMul1)
3690- return {DecompBitMaskMul1, BOp->getOperand (0 )};
3693+ return {DecompBitMaskMul1, BOp->getOperand (1 ), BOp-> getOperand ( 0 )};
36913694
3692- return {std:: nullopt , nullptr } ;
3695+ return CombinedBitmaskMul () ;
36933696}
36943697
36953698// FIXME: We use commutative matchers (m_c_*) for some, but not all, matches
@@ -3778,43 +3781,44 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
37783781 // This also accepts the equivalent select form of (A & N) * C
37793782 // expressions i.e. !(A & N) ? 0 : N * C)
37803783 CombinedBitmaskMul Decomp1 = matchCombinedBitmaskMul (I.getOperand (1 ));
3781- auto BMDecomp1 = Decomp1.first ;
3784+ auto BMDecomp1 = Decomp1.Decomp ;
37823785
37833786 if (BMDecomp1) {
37843787 CombinedBitmaskMul Decomp0 = matchCombinedBitmaskMul (I.getOperand (0 ));
3785- auto BMDecomp0 = Decomp0.first ;
3786-
3787- if (BMDecomp0 && BMDecomp0->isCombineableWith (*BMDecomp1)) {
3788- auto NewAnd = Builder.CreateAnd (
3789- BMDecomp0->X ,
3790- ConstantInt::get (BMDecomp0->X ->getType (),
3791- (BMDecomp0->Mask + BMDecomp1->Mask )));
3792-
3793- BinaryOperator *Combined = cast<BinaryOperator>(Builder.CreateMul (
3794- NewAnd, ConstantInt::get (NewAnd->getType (), BMDecomp1->Factor )));
3788+ auto BMDecomp0 = Decomp0.Decomp ;
37953789
3796- Combined->setHasNoUnsignedWrap (BMDecomp0->NUW && BMDecomp1->NUW );
3797- Combined->setHasNoSignedWrap (BMDecomp0->NSW && BMDecomp1->NSW );
3790+ if (BMDecomp0) {
3791+ // If we have independent operands in the BitmaskMul chain, then just
3792+ // reassociate to encourage combining in future iterations.
3793+ if (Decomp0.OtherOp || Decomp1.OtherOp ) {
3794+ Value *OtherOp = Decomp0.OtherOp ? Decomp0.OtherOp : Decomp1.OtherOp ;
37983795
3799- // If our tree has indepdent or-disjoint operands, bring them in.
3800- auto OtherOp0 = Decomp0.second ;
3801- auto OtherOp1 = Decomp1.second ;
3802-
3803- if (OtherOp0 || OtherOp1) {
3804- Value *OtherOp;
3805- if (OtherOp0 && OtherOp1) {
3806- OtherOp = Builder.CreateOr (OtherOp0, OtherOp1);
3796+ if (Decomp0.OtherOp && Decomp1.OtherOp ) {
3797+ OtherOp = Builder.CreateOr (Decomp0.OtherOp , Decomp1.OtherOp );
38073798 cast<PossiblyDisjointInst>(OtherOp)->setIsDisjoint (true );
3808- } else {
3809- OtherOp = OtherOp0 ? OtherOp0 : OtherOp1;
38103799 }
3811- Combined = cast<BinaryOperator>(Builder.CreateOr (Combined, OtherOp));
3812- cast<PossiblyDisjointInst>(Combined)->setIsDisjoint (true );
3800+
3801+ auto CombinedOp =
3802+ Builder.CreateOr (Decomp0.DecompOp , Decomp1.DecompOp );
3803+ cast<PossiblyDisjointInst>(CombinedOp)->setIsDisjoint (true );
3804+
3805+ return BinaryOperator::CreateDisjointOr (CombinedOp, OtherOp);
38133806 }
38143807
3815- // Caller expects detached instruction
3816- Combined->removeFromParent ();
3817- return Combined;
3808+ if (BMDecomp0->isCombineableWith (*BMDecomp1)) {
3809+ auto NewAnd = Builder.CreateAnd (
3810+ BMDecomp0->X ,
3811+ ConstantInt::get (BMDecomp0->X ->getType (),
3812+ (BMDecomp0->Mask + BMDecomp1->Mask )));
3813+
3814+ auto *Combined = BinaryOperator::CreateMul (
3815+ NewAnd, ConstantInt::get (NewAnd->getType (), BMDecomp1->Factor ));
3816+
3817+ Combined->setHasNoUnsignedWrap (BMDecomp0->NUW && BMDecomp1->NUW );
3818+ Combined->setHasNoSignedWrap (BMDecomp0->NSW && BMDecomp1->NSW );
3819+
3820+ return Combined;
3821+ }
38183822 }
38193823 }
38203824 }
0 commit comments