@@ -4009,23 +4009,16 @@ bool VectorCombine::shrinkPhiOfShuffles(Instruction &I) {
4009
4009
if (!Shuf0 || !Shuf1)
4010
4010
return false ;
4011
4011
4012
- if (!Shuf0->hasOneUse () && !Shuf1->hasOneUse ())
4013
- return false ;
4014
-
4015
- auto *Shuf0Op0 = Shuf0->getOperand (0u );
4016
- auto *Shuf0Op1 = Shuf0->getOperand (1u );
4017
- auto *Shuf1Op0 = Shuf1->getOperand (0u );
4018
- auto *Shuf1Op1 = Shuf1->getOperand (1u );
4019
-
4020
- auto IsPoison = [](Value *Val) -> bool {
4021
- return isa<PoisonValue>(Val) || isa<UndefValue>(Val);
4022
- };
4012
+ Value *Op0 = nullptr ;
4013
+ Value *Op1 = nullptr ;
4023
4014
4024
- if (Shuf0Op0 != Shuf1Op0 || !IsPoison (Shuf0Op1) || !IsPoison (Shuf1Op1))
4015
+ if (!match (Shuf0, m_OneUse (m_Shuffle (m_Value (Op0), m_Poison ()))) ||
4016
+ !match (Shuf1, m_OneUse (m_Shuffle (m_Value (Op1), m_Poison ()))) ||
4017
+ Op0 != Op1)
4025
4018
return false ;
4026
4019
4027
4020
// Ensure result vectors are wider than the argument vector.
4028
- auto *InputVT = cast<FixedVectorType>(Shuf0Op0 ->getType ());
4021
+ auto *InputVT = cast<FixedVectorType>(Op0 ->getType ());
4029
4022
auto *ResultVT = cast<FixedVectorType>(Shuf0->getType ());
4030
4023
auto const InputNumElements = InputVT->getNumElements ();
4031
4024
@@ -4034,46 +4027,43 @@ bool VectorCombine::shrinkPhiOfShuffles(Instruction &I) {
4034
4027
4035
4028
// Take the difference of the two shuffle masks at each index. Ignore poison
4036
4029
// values at the same index in both masks.
4037
- auto Mask0 = Shuf0->getShuffleMask ();
4038
- auto Mask1 = Shuf1->getShuffleMask ();
4039
- auto NewMask0 = std::vector <int >() ;
4040
- NewMask0 .reserve (Mask0.size ());
4030
+ ArrayRef Mask0 = Shuf0->getShuffleMask ();
4031
+ ArrayRef Mask1 = Shuf1->getShuffleMask ();
4032
+ SmallVector <int , 16 > NewMask ;
4033
+ NewMask .reserve (Mask0.size ());
4041
4034
4042
4035
for (auto I = 0u ; I < Mask0.size (); ++I) {
4043
4036
if (Mask0[I] >= 0 && Mask1[I] >= 0 )
4044
- NewMask0 .push_back (Mask0[I] - Mask1[I]);
4037
+ NewMask .push_back (Mask0[I] - Mask1[I]);
4045
4038
else if (Mask0[I] == -1 && Mask1[I] == -1 )
4046
4039
continue ;
4047
4040
else
4048
4041
return false ;
4049
4042
}
4050
4043
4051
- if (NewMask0.empty () ||
4052
- !std::equal (NewMask0.begin () + 1u , NewMask0.end (), NewMask0.begin ()))
4044
+ // Ensure all elements of the new mask are equal. If the difference between
4045
+ // the incoming mask elements is the same, the two must be constant offsets
4046
+ // of one another.
4047
+ if (NewMask.empty () ||
4048
+ !std::equal (NewMask.begin () + 1u , NewMask.end (), NewMask.begin ()))
4053
4049
return false ;
4054
4050
4055
4051
// Create new mask using difference of the two incoming masks.
4056
- auto MaskOffset = NewMask0[0u ];
4057
- if (!Shuf0->hasOneUse ()) {
4058
- std::swap (Shuf0, Shuf1);
4059
- std::swap (Mask0, Mask1);
4060
- MaskOffset *= -1 ;
4061
- }
4062
-
4063
- auto Index = (InputNumElements - MaskOffset) % InputNumElements;
4064
- NewMask0.clear ();
4052
+ int MaskOffset = NewMask[0u ];
4053
+ unsigned Index = (InputNumElements - MaskOffset) % InputNumElements;
4054
+ NewMask.clear ();
4065
4055
4066
- for (auto I = 0u ; I < InputNumElements; ++I) {
4067
- NewMask0 .push_back (Index);
4056
+ for (unsigned I = 0u ; I < InputNumElements; ++I) {
4057
+ NewMask .push_back (Index);
4068
4058
Index = (Index + 1u ) % InputNumElements;
4069
4059
}
4070
4060
4071
4061
// Calculate costs for worst cases and compare.
4072
4062
auto const Kind = TTI::SK_PermuteSingleSrc;
4073
- auto OldCost = std::max (TTI.getShuffleCost (Kind, InputVT, ResultVT, Mask0, CostKind),
4074
- TTI.getShuffleCost (Kind, InputVT, ResultVT, Mask1, CostKind));
4075
- auto NewCost = TTI.getShuffleCost (Kind, InputVT, InputVT, NewMask0 , CostKind) +
4076
- TTI.getShuffleCost (Kind, InputVT, ResultVT, Mask1, CostKind);
4063
+ auto OldCost = std::max (TTI.getShuffleCost (Kind, InputVT, Mask0, CostKind),
4064
+ TTI.getShuffleCost (Kind, InputVT, Mask1, CostKind));
4065
+ auto NewCost = TTI.getShuffleCost (Kind, InputVT, NewMask , CostKind) +
4066
+ TTI.getShuffleCost (Kind, InputVT, Mask1, CostKind);
4077
4067
4078
4068
if (NewCost > OldCost)
4079
4069
return false ;
@@ -4082,17 +4072,18 @@ bool VectorCombine::shrinkPhiOfShuffles(Instruction &I) {
4082
4072
auto Builder = IRBuilder (&I);
4083
4073
Builder.SetInsertPoint (Shuf0);
4084
4074
Builder.SetCurrentDebugLocation (Shuf0->getDebugLoc ());
4085
- auto *NewShuf0 = Builder.CreateShuffleVector (Shuf0Op0, Shuf0Op1, NewMask0);
4075
+ auto *PoisonVal = PoisonValue::get (InputVT);
4076
+ auto *NewShuf0 = Builder.CreateShuffleVector (Op0, PoisonVal, NewMask);
4086
4077
4087
4078
Builder.SetInsertPoint (Phi);
4088
4079
Builder.SetCurrentDebugLocation (Phi->getDebugLoc ());
4089
4080
auto *NewPhi = Builder.CreatePHI (NewShuf0->getType (), 2u );
4090
4081
NewPhi->addIncoming (NewShuf0, Phi->getIncomingBlock (0u ));
4091
- NewPhi->addIncoming (Shuf1Op0 , Phi->getIncomingBlock (1u ));
4082
+ NewPhi->addIncoming (Op1 , Phi->getIncomingBlock (1u ));
4092
4083
4093
4084
Builder.SetInsertPoint (*NewPhi->getInsertionPointAfterDef ());
4094
- auto *NewPoison = PoisonValue::get (NewPhi->getType ());
4095
- auto *NewShuf2 = Builder.CreateShuffleVector (NewPhi, NewPoison , Mask1);
4085
+ PoisonVal = PoisonValue::get (NewPhi->getType ());
4086
+ auto *NewShuf2 = Builder.CreateShuffleVector (NewPhi, PoisonVal , Mask1);
4096
4087
4097
4088
replaceValue (*Phi, *NewShuf2);
4098
4089
return true ;
0 commit comments