@@ -55,14 +55,14 @@ static bool CheapToScalarize(Value *V, bool isConstant) {
55
55
56
56
// / getShuffleMask - Read and decode a shufflevector mask.
57
57
// / Turn undef elements into negative values.
58
- static std::vector <int > getShuffleMask (const ShuffleVectorInst *SVI) {
58
+ static SmallVector <int , 16 > getShuffleMask (const ShuffleVectorInst *SVI) {
59
59
unsigned NElts = SVI->getType ()->getNumElements ();
60
60
if (isa<ConstantAggregateZero>(SVI->getOperand (2 )))
61
- return std::vector <int >(NElts, 0 );
61
+ return SmallVector <int , 16 >(NElts, 0 );
62
62
if (isa<UndefValue>(SVI->getOperand (2 )))
63
- return std::vector <int >(NElts, -1 );
63
+ return SmallVector <int , 16 >(NElts, -1 );
64
64
65
- std::vector <int > Result;
65
+ SmallVector <int , 16 > Result;
66
66
const ConstantVector *CP = cast<ConstantVector>(SVI->getOperand (2 ));
67
67
for (User::const_op_iterator i = CP->op_begin (), e = CP->op_end (); i!=e; ++i)
68
68
if (isa<UndefValue>(*i))
@@ -447,7 +447,7 @@ Instruction *InstCombiner::visitInsertElementInst(InsertElementInst &IE) {
447
447
Instruction *InstCombiner::visitShuffleVectorInst (ShuffleVectorInst &SVI) {
448
448
Value *LHS = SVI.getOperand (0 );
449
449
Value *RHS = SVI.getOperand (1 );
450
- std::vector <int > Mask = getShuffleMask (&SVI);
450
+ SmallVector <int , 16 > Mask = getShuffleMask (&SVI);
451
451
452
452
bool MadeChange = false ;
453
453
@@ -457,9 +457,6 @@ Instruction *InstCombiner::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
457
457
458
458
unsigned VWidth = cast<VectorType>(SVI.getType ())->getNumElements ();
459
459
460
- if (VWidth != cast<VectorType>(LHS->getType ())->getNumElements ())
461
- return 0 ;
462
-
463
460
APInt UndefElts (VWidth, 0 );
464
461
APInt AllOnesEltMask (APInt::getAllOnesValue (VWidth));
465
462
if (Value *V = SimplifyDemandedVectorElts (&SVI, AllOnesEltMask, UndefElts)) {
@@ -470,17 +467,21 @@ Instruction *InstCombiner::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
470
467
MadeChange = true ;
471
468
}
472
469
470
+ unsigned LHSWidth = cast<VectorType>(LHS->getType ())->getNumElements ();
471
+
473
472
// Canonicalize shuffle(x ,x,mask) -> shuffle(x, undef,mask')
474
473
// Canonicalize shuffle(undef,x,mask) -> shuffle(x, undef,mask').
475
474
if (LHS == RHS || isa<UndefValue>(LHS)) {
476
475
if (isa<UndefValue>(LHS) && LHS == RHS) {
477
476
// shuffle(undef,undef,mask) -> undef.
478
- return ReplaceInstUsesWith (SVI, LHS);
477
+ Value* result = (VWidth == LHSWidth)
478
+ ? LHS : UndefValue::get (SVI.getType ());
479
+ return ReplaceInstUsesWith (SVI, result);
479
480
}
480
481
481
482
// Remap any references to RHS to use LHS.
482
483
std::vector<Constant*> Elts;
483
- for (unsigned i = 0 , e = Mask. size () ; i != e ; ++i) {
484
+ for (unsigned i = 0 , e = LHSWidth ; i != VWidth ; ++i) {
484
485
if (Mask[i] < 0 )
485
486
Elts.push_back (UndefValue::get (Type::getInt32Ty (SVI.getContext ())));
486
487
else {
@@ -503,72 +504,205 @@ Instruction *InstCombiner::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
503
504
MadeChange = true ;
504
505
}
505
506
506
- // Analyze the shuffle, are the LHS or RHS and identity shuffles?
507
- bool isLHSID = true , isRHSID = true ;
507
+ if (VWidth == LHSWidth) {
508
+ // Analyze the shuffle, are the LHS or RHS and identity shuffles?
509
+ bool isLHSID = true , isRHSID = true ;
510
+
511
+ for (unsigned i = 0 , e = Mask.size (); i != e; ++i) {
512
+ if (Mask[i] < 0 ) continue ; // Ignore undef values.
513
+ // Is this an identity shuffle of the LHS value?
514
+ isLHSID &= (Mask[i] == (int )i);
508
515
509
- for (unsigned i = 0 , e = Mask.size (); i != e; ++i) {
510
- if (Mask[i] < 0 ) continue ; // Ignore undef values.
511
- // Is this an identity shuffle of the LHS value?
512
- isLHSID &= (Mask[i] == (int )i);
516
+ // Is this an identity shuffle of the RHS value?
517
+ isRHSID &= (Mask[i]-e == i);
518
+ }
513
519
514
- // Is this an identity shuffle of the RHS value?
515
- isRHSID &= (Mask[i]-e == i);
520
+ // Eliminate identity shuffles.
521
+ if (isLHSID) return ReplaceInstUsesWith (SVI, LHS);
522
+ if (isRHSID) return ReplaceInstUsesWith (SVI, RHS);
516
523
}
517
524
518
- // Eliminate identity shuffles.
519
- if (isLHSID) return ReplaceInstUsesWith (SVI, LHS);
520
- if (isRHSID) return ReplaceInstUsesWith (SVI, RHS);
521
-
522
525
// If the LHS is a shufflevector itself, see if we can combine it with this
523
- // one without producing an unusual shuffle. Here we are really conservative:
526
+ // one without producing an unusual shuffle.
527
+ // Cases that might be simplified:
528
+ // 1.
529
+ // x1=shuffle(v1,v2,mask1)
530
+ // x=shuffle(x1,undef,mask)
531
+ // ==>
532
+ // x=shuffle(v1,undef,newMask)
533
+ // newMask[i] = (mask[i] < x1.size()) ? mask1[mask[i]] : -1
534
+ // 2.
535
+ // x1=shuffle(v1,undef,mask1)
536
+ // x=shuffle(x1,x2,mask)
537
+ // where v1.size() == mask1.size()
538
+ // ==>
539
+ // x=shuffle(v1,x2,newMask)
540
+ // newMask[i] = (mask[i] < x1.size()) ? mask1[mask[i]] : mask[i]
541
+ // 3.
542
+ // x2=shuffle(v2,undef,mask2)
543
+ // x=shuffle(x1,x2,mask)
544
+ // where v2.size() == mask2.size()
545
+ // ==>
546
+ // x=shuffle(x1,v2,newMask)
547
+ // newMask[i] = (mask[i] < x1.size())
548
+ // ? mask[i] : mask2[mask[i]-x1.size()]+x1.size()
549
+ // 4.
550
+ // x1=shuffle(v1,undef,mask1)
551
+ // x2=shuffle(v2,undef,mask2)
552
+ // x=shuffle(x1,x2,mask)
553
+ // where v1.size() == v2.size()
554
+ // ==>
555
+ // x=shuffle(v1,v2,newMask)
556
+ // newMask[i] = (mask[i] < x1.size())
557
+ // ? mask1[mask[i]] : mask2[mask[i]-x1.size()]+v1.size()
558
+ //
559
+ // Here we are really conservative:
524
560
// we are absolutely afraid of producing a shuffle mask not in the input
525
561
// program, because the code gen may not be smart enough to turn a merged
526
562
// shuffle into two specific shuffles: it may produce worse code. As such,
527
563
// we only merge two shuffles if the result is either a splat or one of the
528
- // two input shuffle masks. In this case, merging the shuffles just removes
564
+ // input shuffle masks. In this case, merging the shuffles just removes
529
565
// one instruction, which we know is safe. This is good for things like
530
- // turning: (splat(splat)) -> splat.
531
- if (ShuffleVectorInst *LHSSVI = dyn_cast<ShuffleVectorInst>(LHS)) {
566
+ // turning: (splat(splat)) -> splat, or
567
+ // merge(V[0..n], V[n+1..2n]) -> V[0..2n]
568
+ ShuffleVectorInst* LHSShuffle = dyn_cast<ShuffleVectorInst>(LHS);
569
+ ShuffleVectorInst* RHSShuffle = dyn_cast<ShuffleVectorInst>(RHS);
570
+ if (LHSShuffle)
571
+ if (!isa<UndefValue>(LHSShuffle->getOperand (1 )) && !isa<UndefValue>(RHS))
572
+ LHSShuffle = NULL ;
573
+ if (RHSShuffle)
574
+ if (!isa<UndefValue>(RHSShuffle->getOperand (1 )))
575
+ RHSShuffle = NULL ;
576
+ if (!LHSShuffle && !RHSShuffle)
577
+ return MadeChange ? &SVI : 0 ;
578
+
579
+ Value* LHSOp0 = NULL ;
580
+ Value* LHSOp1 = NULL ;
581
+ Value* RHSOp0 = NULL ;
582
+ unsigned LHSOp0Width = 0 ;
583
+ unsigned RHSOp0Width = 0 ;
584
+ if (LHSShuffle) {
585
+ LHSOp0 = LHSShuffle->getOperand (0 );
586
+ LHSOp1 = LHSShuffle->getOperand (1 );
587
+ LHSOp0Width = cast<VectorType>(LHSOp0->getType ())->getNumElements ();
588
+ }
589
+ if (RHSShuffle) {
590
+ RHSOp0 = RHSShuffle->getOperand (0 );
591
+ RHSOp0Width = cast<VectorType>(RHSOp0->getType ())->getNumElements ();
592
+ }
593
+ Value* newLHS = LHS;
594
+ Value* newRHS = RHS;
595
+ if (LHSShuffle) {
596
+ // case 1
532
597
if (isa<UndefValue>(RHS)) {
533
- std::vector<int > LHSMask = getShuffleMask (LHSSVI);
534
-
535
- if (LHSMask.size () == Mask.size ()) {
536
- std::vector<int > NewMask;
537
- bool isSplat = true ;
538
- int SplatElt = -1 ; // undef
539
- for (unsigned i = 0 , e = Mask.size (); i != e; ++i) {
540
- int MaskElt;
541
- if (Mask[i] < 0 || Mask[i] >= (int )e)
542
- MaskElt = -1 ; // undef
543
- else
544
- MaskElt = LHSMask[Mask[i]];
545
- // Check if this could still be a splat.
546
- if (MaskElt >= 0 ) {
547
- if (SplatElt >=0 && SplatElt != MaskElt)
548
- isSplat = false ;
549
- SplatElt = MaskElt;
550
- }
551
- NewMask.push_back (MaskElt);
552
- }
598
+ newLHS = LHSOp0;
599
+ newRHS = LHSOp1;
600
+ }
601
+ // case 2 or 4
602
+ else if (LHSOp0Width == LHSWidth) {
603
+ newLHS = LHSOp0;
604
+ }
605
+ }
606
+ // case 3 or 4
607
+ if (RHSShuffle && RHSOp0Width == LHSWidth) {
608
+ newRHS = RHSOp0;
609
+ }
610
+ // case 4
611
+ if (LHSOp0 == RHSOp0) {
612
+ newLHS = LHSOp0;
613
+ newRHS = NULL ;
614
+ }
553
615
554
- // If the result mask is equal to the src shuffle or this
555
- // shuffle mask, do the replacement.
556
- if (isSplat || NewMask == LHSMask || NewMask == Mask) {
557
- std::vector<Constant*> Elts;
558
- Type *Int32Ty = Type::getInt32Ty (SVI.getContext ());
559
- for (unsigned i = 0 , e = NewMask.size (); i != e; ++i) {
560
- if (NewMask[i] < 0 ) {
561
- Elts.push_back (UndefValue::get (Int32Ty));
562
- } else {
563
- Elts.push_back (ConstantInt::get (Int32Ty, NewMask[i]));
564
- }
565
- }
566
- return new ShuffleVectorInst (LHSSVI->getOperand (0 ),
567
- LHSSVI->getOperand (1 ),
568
- ConstantVector::get (Elts));
616
+ if (newLHS == LHS && newRHS == RHS)
617
+ return MadeChange ? &SVI : 0 ;
618
+
619
+ SmallVector<int , 16 > LHSMask;
620
+ SmallVector<int , 16 > RHSMask;
621
+ if (newLHS != LHS) {
622
+ LHSMask = getShuffleMask (LHSShuffle);
623
+ }
624
+ if (RHSShuffle && newRHS != RHS) {
625
+ RHSMask = getShuffleMask (RHSShuffle);
626
+ }
627
+ unsigned newLHSWidth = (newLHS != LHS) ? LHSOp0Width : LHSWidth;
628
+ SmallVector<int , 16 > newMask;
629
+ bool isSplat = true ;
630
+ int SplatElt = -1 ;
631
+ // Create a new mask for the new ShuffleVectorInst so that the new
632
+ // ShuffleVectorInst is equivalent to the original one.
633
+ for (unsigned i = 0 ; i < VWidth; ++i) {
634
+ int eltMask;
635
+ if (Mask[i] == -1 ) {
636
+ // This element is an undef value.
637
+ eltMask = -1 ;
638
+ } else if (Mask[i] < (int )LHSWidth) {
639
+ // This element is from left hand side vector operand.
640
+ //
641
+ // If LHS is going to be replaced (case 1, 2, or 4), calculate the
642
+ // new mask value for the element.
643
+ if (newLHS != LHS) {
644
+ eltMask = LHSMask[Mask[i]];
645
+ // If the value selected is an undef value, explicitly specify it
646
+ // with a -1 mask value.
647
+ if (eltMask >= (int )LHSOp0Width && isa<UndefValue>(LHSOp1))
648
+ eltMask = -1 ;
649
+ }
650
+ else
651
+ eltMask = Mask[i];
652
+ } else {
653
+ // This element is from right hand side vector operand
654
+ //
655
+ // If the value selected is an undef value, explicitly specify it
656
+ // with a -1 mask value. (case 1)
657
+ if (isa<UndefValue>(RHS))
658
+ eltMask = -1 ;
659
+ // If RHS is going to be replaced (case 3 or 4), calculate the
660
+ // new mask value for the element.
661
+ else if (newRHS != RHS) {
662
+ eltMask = RHSMask[Mask[i]-LHSWidth];
663
+ // If the value selected is an undef value, explicitly specify it
664
+ // with a -1 mask value.
665
+ if (eltMask >= (int )RHSOp0Width) {
666
+ assert (isa<UndefValue>(RHSShuffle->getOperand (1 ))
667
+ && " should have been check above" );
668
+ eltMask = -1 ;
569
669
}
570
670
}
671
+ else
672
+ eltMask = Mask[i]-LHSWidth;
673
+
674
+ // If LHS's width is changed, shift the mask value accordingly.
675
+ // If newRHS == NULL, i.e. LHSOp0 == RHSOp0, we want to remap any
676
+ // references to RHSOp0 to LHSOp0, so we don't need to shift the mask.
677
+ if (eltMask >= 0 && newRHS != NULL )
678
+ eltMask += newLHSWidth;
679
+ }
680
+
681
+ // Check if this could still be a splat.
682
+ if (eltMask >= 0 ) {
683
+ if (SplatElt >= 0 && SplatElt != eltMask)
684
+ isSplat = false ;
685
+ SplatElt = eltMask;
686
+ }
687
+
688
+ newMask.push_back (eltMask);
689
+ }
690
+
691
+ // If the result mask is equal to one of the original shuffle masks,
692
+ // or is a splat, do the replacement.
693
+ if (isSplat || newMask == LHSMask || newMask == RHSMask || newMask == Mask) {
694
+ SmallVector<Constant*, 16 > Elts;
695
+ Type *Int32Ty = Type::getInt32Ty (SVI.getContext ());
696
+ for (unsigned i = 0 , e = newMask.size (); i != e; ++i) {
697
+ if (newMask[i] < 0 ) {
698
+ Elts.push_back (UndefValue::get (Int32Ty));
699
+ } else {
700
+ Elts.push_back (ConstantInt::get (Int32Ty, newMask[i]));
701
+ }
571
702
}
703
+ if (newRHS == NULL )
704
+ newRHS = UndefValue::get (newLHS->getType ());
705
+ return new ShuffleVectorInst (newLHS, newRHS, ConstantVector::get (Elts));
572
706
}
573
707
574
708
return MadeChange ? &SVI : 0 ;
0 commit comments