@@ -3498,23 +3498,16 @@ bool VectorCombine::shrinkPhiOfShuffles(Instruction &I) {
3498
3498
if (!Shuf0 || !Shuf1)
3499
3499
return false ;
3500
3500
3501
- if (!Shuf0->hasOneUse () && !Shuf1->hasOneUse ())
3502
- return false ;
3503
-
3504
- auto *Shuf0Op0 = Shuf0->getOperand (0u );
3505
- auto *Shuf0Op1 = Shuf0->getOperand (1u );
3506
- auto *Shuf1Op0 = Shuf1->getOperand (0u );
3507
- auto *Shuf1Op1 = Shuf1->getOperand (1u );
3508
-
3509
- auto IsPoison = [](Value *Val) -> bool {
3510
- return isa<PoisonValue>(Val) || isa<UndefValue>(Val);
3511
- };
3501
+ Value *Op0 = nullptr ;
3502
+ Value *Op1 = nullptr ;
3512
3503
3513
- if (Shuf0Op0 != Shuf1Op0 || !IsPoison (Shuf0Op1) || !IsPoison (Shuf1Op1))
3504
+ if (!match (Shuf0, m_OneUse (m_Shuffle (m_Value (Op0), m_Poison ()))) ||
3505
+ !match (Shuf1, m_OneUse (m_Shuffle (m_Value (Op1), m_Poison ()))) ||
3506
+ Op0 != Op1)
3514
3507
return false ;
3515
3508
3516
3509
// Ensure result vectors are wider than the argument vector.
3517
- auto *InputVT = cast<FixedVectorType>(Shuf0Op0 ->getType ());
3510
+ auto *InputVT = cast<FixedVectorType>(Op0 ->getType ());
3518
3511
auto *ResultVT = cast<FixedVectorType>(Shuf0->getType ());
3519
3512
auto const InputNumElements = InputVT->getNumElements ();
3520
3513
@@ -3523,45 +3516,42 @@ bool VectorCombine::shrinkPhiOfShuffles(Instruction &I) {
3523
3516
3524
3517
// Take the difference of the two shuffle masks at each index. Ignore poison
3525
3518
// values at the same index in both masks.
3526
- auto Mask0 = Shuf0->getShuffleMask ();
3527
- auto Mask1 = Shuf1->getShuffleMask ();
3528
- auto NewMask0 = std::vector <int >() ;
3529
- NewMask0 .reserve (Mask0.size ());
3519
+ ArrayRef Mask0 = Shuf0->getShuffleMask ();
3520
+ ArrayRef Mask1 = Shuf1->getShuffleMask ();
3521
+ SmallVector <int , 16 > NewMask ;
3522
+ NewMask .reserve (Mask0.size ());
3530
3523
3531
3524
for (auto I = 0u ; I < Mask0.size (); ++I) {
3532
3525
if (Mask0[I] >= 0 && Mask1[I] >= 0 )
3533
- NewMask0 .push_back (Mask0[I] - Mask1[I]);
3526
+ NewMask .push_back (Mask0[I] - Mask1[I]);
3534
3527
else if (Mask0[I] == -1 && Mask1[I] == -1 )
3535
3528
continue ;
3536
3529
else
3537
3530
return false ;
3538
3531
}
3539
3532
3540
- if (NewMask0.empty () ||
3541
- !std::equal (NewMask0.begin () + 1u , NewMask0.end (), NewMask0.begin ()))
3533
+ // Ensure all elements of the new mask are equal. If the difference between
3534
+ // the incoming mask elements is the same, the two must be constant offsets
3535
+ // of one another.
3536
+ if (NewMask.empty () ||
3537
+ !std::equal (NewMask.begin () + 1u , NewMask.end (), NewMask.begin ()))
3542
3538
return false ;
3543
3539
3544
3540
// Create new mask using difference of the two incoming masks.
3545
- auto MaskOffset = NewMask0[0u ];
3546
- if (!Shuf0->hasOneUse ()) {
3547
- std::swap (Shuf0, Shuf1);
3548
- std::swap (Mask0, Mask1);
3549
- MaskOffset *= -1 ;
3550
- }
3551
-
3552
- auto Index = (InputNumElements - MaskOffset) % InputNumElements;
3553
- NewMask0.clear ();
3541
+ int MaskOffset = NewMask[0u ];
3542
+ unsigned Index = (InputNumElements - MaskOffset) % InputNumElements;
3543
+ NewMask.clear ();
3554
3544
3555
- for (auto I = 0u ; I < InputNumElements; ++I) {
3556
- NewMask0 .push_back (Index);
3545
+ for (unsigned I = 0u ; I < InputNumElements; ++I) {
3546
+ NewMask .push_back (Index);
3557
3547
Index = (Index + 1u ) % InputNumElements;
3558
3548
}
3559
3549
3560
3550
// Calculate costs for worst cases and compare.
3561
3551
auto const Kind = TTI::SK_PermuteSingleSrc;
3562
3552
auto OldCost = std::max (TTI.getShuffleCost (Kind, InputVT, Mask0, CostKind),
3563
3553
TTI.getShuffleCost (Kind, InputVT, Mask1, CostKind));
3564
- auto NewCost = TTI.getShuffleCost (Kind, InputVT, NewMask0 , CostKind) +
3554
+ auto NewCost = TTI.getShuffleCost (Kind, InputVT, NewMask , CostKind) +
3565
3555
TTI.getShuffleCost (Kind, InputVT, Mask1, CostKind);
3566
3556
3567
3557
if (NewCost > OldCost)
@@ -3571,17 +3561,18 @@ bool VectorCombine::shrinkPhiOfShuffles(Instruction &I) {
3571
3561
auto Builder = IRBuilder (&I);
3572
3562
Builder.SetInsertPoint (Shuf0);
3573
3563
Builder.SetCurrentDebugLocation (Shuf0->getDebugLoc ());
3574
- auto *NewShuf0 = Builder.CreateShuffleVector (Shuf0Op0, Shuf0Op1, NewMask0);
3564
+ auto *PoisonVal = PoisonValue::get (InputVT);
3565
+ auto *NewShuf0 = Builder.CreateShuffleVector (Op0, PoisonVal, NewMask);
3575
3566
3576
3567
Builder.SetInsertPoint (Phi);
3577
3568
Builder.SetCurrentDebugLocation (Phi->getDebugLoc ());
3578
3569
auto *NewPhi = Builder.CreatePHI (NewShuf0->getType (), 2u );
3579
3570
NewPhi->addIncoming (NewShuf0, Phi->getIncomingBlock (0u ));
3580
- NewPhi->addIncoming (Shuf1Op0 , Phi->getIncomingBlock (1u ));
3571
+ NewPhi->addIncoming (Op1 , Phi->getIncomingBlock (1u ));
3581
3572
3582
3573
Builder.SetInsertPoint (*NewPhi->getInsertionPointAfterDef ());
3583
- auto *NewPoison = PoisonValue::get (NewPhi->getType ());
3584
- auto *NewShuf2 = Builder.CreateShuffleVector (NewPhi, NewPoison , Mask1);
3574
+ PoisonVal = PoisonValue::get (NewPhi->getType ());
3575
+ auto *NewShuf2 = Builder.CreateShuffleVector (NewPhi, PoisonVal , Mask1);
3585
3576
3586
3577
replaceValue (*Phi, *NewShuf2);
3587
3578
return true ;
0 commit comments