@@ -3706,23 +3706,16 @@ bool VectorCombine::shrinkPhiOfShuffles(Instruction &I) {
3706
3706
if (!Shuf0 || !Shuf1)
3707
3707
return false ;
3708
3708
3709
- if (!Shuf0->hasOneUse () && !Shuf1->hasOneUse ())
3710
- return false ;
3711
-
3712
- auto *Shuf0Op0 = Shuf0->getOperand (0u );
3713
- auto *Shuf0Op1 = Shuf0->getOperand (1u );
3714
- auto *Shuf1Op0 = Shuf1->getOperand (0u );
3715
- auto *Shuf1Op1 = Shuf1->getOperand (1u );
3716
-
3717
- auto IsPoison = [](Value *Val) -> bool {
3718
- return isa<PoisonValue>(Val) || isa<UndefValue>(Val);
3719
- };
3709
+ Value *Op0 = nullptr ;
3710
+ Value *Op1 = nullptr ;
3720
3711
3721
- if (Shuf0Op0 != Shuf1Op0 || !IsPoison (Shuf0Op1) || !IsPoison (Shuf1Op1))
3712
+ if (!match (Shuf0, m_OneUse (m_Shuffle (m_Value (Op0), m_Poison ()))) ||
3713
+ !match (Shuf1, m_OneUse (m_Shuffle (m_Value (Op1), m_Poison ()))) ||
3714
+ Op0 != Op1)
3722
3715
return false ;
3723
3716
3724
3717
// Ensure result vectors are wider than the argument vector.
3725
- auto *InputVT = cast<FixedVectorType>(Shuf0Op0 ->getType ());
3718
+ auto *InputVT = cast<FixedVectorType>(Op0 ->getType ());
3726
3719
auto *ResultVT = cast<FixedVectorType>(Shuf0->getType ());
3727
3720
auto const InputNumElements = InputVT->getNumElements ();
3728
3721
@@ -3731,45 +3724,42 @@ bool VectorCombine::shrinkPhiOfShuffles(Instruction &I) {
3731
3724
3732
3725
// Take the difference of the two shuffle masks at each index. Ignore poison
3733
3726
// values at the same index in both masks.
3734
- auto Mask0 = Shuf0->getShuffleMask ();
3735
- auto Mask1 = Shuf1->getShuffleMask ();
3736
- auto NewMask0 = std::vector <int >() ;
3737
- NewMask0 .reserve (Mask0.size ());
3727
+ ArrayRef Mask0 = Shuf0->getShuffleMask ();
3728
+ ArrayRef Mask1 = Shuf1->getShuffleMask ();
3729
+ SmallVector <int , 16 > NewMask ;
3730
+ NewMask .reserve (Mask0.size ());
3738
3731
3739
3732
for (auto I = 0u ; I < Mask0.size (); ++I) {
3740
3733
if (Mask0[I] >= 0 && Mask1[I] >= 0 )
3741
- NewMask0 .push_back (Mask0[I] - Mask1[I]);
3734
+ NewMask .push_back (Mask0[I] - Mask1[I]);
3742
3735
else if (Mask0[I] == -1 && Mask1[I] == -1 )
3743
3736
continue ;
3744
3737
else
3745
3738
return false ;
3746
3739
}
3747
3740
3748
- if (NewMask0.empty () ||
3749
- !std::equal (NewMask0.begin () + 1u , NewMask0.end (), NewMask0.begin ()))
3741
+ // Ensure all elements of the new mask are equal. If the difference between
3742
+ // the incoming mask elements is the same, the two must be constant offsets
3743
+ // of one another.
3744
+ if (NewMask.empty () ||
3745
+ !std::equal (NewMask.begin () + 1u , NewMask.end (), NewMask.begin ()))
3750
3746
return false ;
3751
3747
3752
3748
// Create new mask using difference of the two incoming masks.
3753
- auto MaskOffset = NewMask0[0u ];
3754
- if (!Shuf0->hasOneUse ()) {
3755
- std::swap (Shuf0, Shuf1);
3756
- std::swap (Mask0, Mask1);
3757
- MaskOffset *= -1 ;
3758
- }
3759
-
3760
- auto Index = (InputNumElements - MaskOffset) % InputNumElements;
3761
- NewMask0.clear ();
3749
+ int MaskOffset = NewMask[0u ];
3750
+ unsigned Index = (InputNumElements - MaskOffset) % InputNumElements;
3751
+ NewMask.clear ();
3762
3752
3763
- for (auto I = 0u ; I < InputNumElements; ++I) {
3764
- NewMask0 .push_back (Index);
3753
+ for (unsigned I = 0u ; I < InputNumElements; ++I) {
3754
+ NewMask .push_back (Index);
3765
3755
Index = (Index + 1u ) % InputNumElements;
3766
3756
}
3767
3757
3768
3758
// Calculate costs for worst cases and compare.
3769
3759
auto const Kind = TTI::SK_PermuteSingleSrc;
3770
3760
auto OldCost = std::max (TTI.getShuffleCost (Kind, InputVT, Mask0, CostKind),
3771
3761
TTI.getShuffleCost (Kind, InputVT, Mask1, CostKind));
3772
- auto NewCost = TTI.getShuffleCost (Kind, InputVT, NewMask0 , CostKind) +
3762
+ auto NewCost = TTI.getShuffleCost (Kind, InputVT, NewMask , CostKind) +
3773
3763
TTI.getShuffleCost (Kind, InputVT, Mask1, CostKind);
3774
3764
3775
3765
if (NewCost > OldCost)
@@ -3779,17 +3769,18 @@ bool VectorCombine::shrinkPhiOfShuffles(Instruction &I) {
3779
3769
auto Builder = IRBuilder (&I);
3780
3770
Builder.SetInsertPoint (Shuf0);
3781
3771
Builder.SetCurrentDebugLocation (Shuf0->getDebugLoc ());
3782
- auto *NewShuf0 = Builder.CreateShuffleVector (Shuf0Op0, Shuf0Op1, NewMask0);
3772
+ auto *PoisonVal = PoisonValue::get (InputVT);
3773
+ auto *NewShuf0 = Builder.CreateShuffleVector (Op0, PoisonVal, NewMask);
3783
3774
3784
3775
Builder.SetInsertPoint (Phi);
3785
3776
Builder.SetCurrentDebugLocation (Phi->getDebugLoc ());
3786
3777
auto *NewPhi = Builder.CreatePHI (NewShuf0->getType (), 2u );
3787
3778
NewPhi->addIncoming (NewShuf0, Phi->getIncomingBlock (0u ));
3788
- NewPhi->addIncoming (Shuf1Op0 , Phi->getIncomingBlock (1u ));
3779
+ NewPhi->addIncoming (Op1 , Phi->getIncomingBlock (1u ));
3789
3780
3790
3781
Builder.SetInsertPoint (*NewPhi->getInsertionPointAfterDef ());
3791
- auto *NewPoison = PoisonValue::get (NewPhi->getType ());
3792
- auto *NewShuf2 = Builder.CreateShuffleVector (NewPhi, NewPoison , Mask1);
3782
+ PoisonVal = PoisonValue::get (NewPhi->getType ());
3783
+ auto *NewShuf2 = Builder.CreateShuffleVector (NewPhi, PoisonVal , Mask1);
3793
3784
3794
3785
replaceValue (*Phi, *NewShuf2);
3795
3786
return true ;
0 commit comments