@@ -1669,63 +1669,59 @@ bool VectorCombine::foldShuffleOfShuffles(Instruction &I) {
1669
1669
return true ;
1670
1670
}
1671
1671
1672
- using InstLane = std::pair<Value *, int >;
1672
+ using InstLane = std::pair<Use *, int >;
1673
1673
1674
- static InstLane lookThroughShuffles (Value *V , int Lane) {
1675
- while (auto *SV = dyn_cast<ShuffleVectorInst>(V )) {
1674
+ static InstLane lookThroughShuffles (Use *U , int Lane) {
1675
+ while (auto *SV = dyn_cast<ShuffleVectorInst>(U-> get () )) {
1676
1676
unsigned NumElts =
1677
1677
cast<FixedVectorType>(SV->getOperand (0 )->getType ())->getNumElements ();
1678
1678
int M = SV->getMaskValue (Lane);
1679
1679
if (M < 0 )
1680
1680
return {nullptr , PoisonMaskElem};
1681
1681
if (static_cast <unsigned >(M) < NumElts) {
1682
- V = SV->getOperand (0 );
1682
+ U = & SV->getOperandUse (0 );
1683
1683
Lane = M;
1684
1684
} else {
1685
- V = SV->getOperand (1 );
1685
+ U = & SV->getOperandUse (1 );
1686
1686
Lane = M - NumElts;
1687
1687
}
1688
1688
}
1689
- return InstLane{V , Lane};
1689
+ return InstLane{U , Lane};
1690
1690
}
1691
1691
1692
1692
static SmallVector<InstLane>
1693
1693
generateInstLaneVectorFromOperand (ArrayRef<InstLane> Item, int Op) {
1694
1694
SmallVector<InstLane> NItem;
1695
1695
for (InstLane IL : Item) {
1696
- auto [V , Lane] = IL;
1696
+ auto [U , Lane] = IL;
1697
1697
InstLane OpLane =
1698
- V ? lookThroughShuffles (cast<Instruction>(V)->getOperand (Op), Lane)
1698
+ U ? lookThroughShuffles (&cast<Instruction>(U->get ())->getOperandUse (Op),
1699
+ Lane)
1699
1700
: InstLane{nullptr , PoisonMaskElem};
1700
1701
NItem.emplace_back (OpLane);
1701
1702
}
1702
1703
return NItem;
1703
1704
}
1704
1705
1705
1706
static Value *generateNewInstTree (ArrayRef<InstLane> Item, FixedVectorType *Ty,
1706
- const SmallPtrSet<Value *, 4 > &IdentityLeafs,
1707
- const SmallPtrSet<Value *, 4 > &SplatLeafs,
1707
+ const SmallPtrSet<Use *, 4 > &IdentityLeafs,
1708
+ const SmallPtrSet<Use *, 4 > &SplatLeafs,
1708
1709
IRBuilder<> &Builder) {
1709
- auto [FrontV, FrontLane] = Item.front ();
1710
-
1711
- if (IdentityLeafs.contains (FrontV) &&
1712
- all_of (drop_begin (enumerate(Item)), [Item](const auto &E) {
1713
- Value *FrontV = Item.front ().first ;
1714
- auto [V, Lane] = E.value ();
1715
- return !V || (V == FrontV && Lane == (int )E.index ());
1716
- })) {
1717
- return FrontV;
1710
+ auto [FrontU, FrontLane] = Item.front ();
1711
+
1712
+ if (IdentityLeafs.contains (FrontU)) {
1713
+ return FrontU->get ();
1718
1714
}
1719
- if (SplatLeafs.contains (FrontV )) {
1720
- if (auto *ILI = dyn_cast<Instruction>(FrontV ))
1715
+ if (SplatLeafs.contains (FrontU )) {
1716
+ if (auto *ILI = dyn_cast<Instruction>(FrontU ))
1721
1717
Builder.SetInsertPoint (*ILI->getInsertionPointAfterDef ());
1722
- else if (auto *Arg = dyn_cast<Argument>(FrontV ))
1718
+ else if (auto *Arg = dyn_cast<Argument>(FrontU ))
1723
1719
Builder.SetInsertPointPastAllocas (Arg->getParent ());
1724
1720
SmallVector<int , 16 > Mask (Ty->getNumElements (), FrontLane);
1725
- return Builder.CreateShuffleVector (FrontV , Mask);
1721
+ return Builder.CreateShuffleVector (FrontU-> get () , Mask);
1726
1722
}
1727
1723
1728
- auto *I = cast<Instruction>(FrontV );
1724
+ auto *I = cast<Instruction>(FrontU-> get () );
1729
1725
auto *II = dyn_cast<IntrinsicInst>(I);
1730
1726
unsigned NumOps = I->getNumOperands () - (II ? 1 : 0 );
1731
1727
SmallVector<Value *> Ops (NumOps);
@@ -1741,7 +1737,7 @@ static Value *generateNewInstTree(ArrayRef<InstLane> Item, FixedVectorType *Ty,
1741
1737
SmallVector<Value *, 8 > ValueList;
1742
1738
for (const auto &Lane : Item)
1743
1739
if (Lane.first )
1744
- ValueList.push_back (Lane.first );
1740
+ ValueList.push_back (Lane.first -> get () );
1745
1741
1746
1742
Builder.SetInsertPoint (I);
1747
1743
Type *DstTy =
@@ -1785,69 +1781,69 @@ static Value *generateNewInstTree(ArrayRef<InstLane> Item, FixedVectorType *Ty,
1785
1781
// do so.
1786
1782
bool VectorCombine::foldShuffleToIdentity (Instruction &I) {
1787
1783
auto *Ty = dyn_cast<FixedVectorType>(I.getType ());
1788
- if (!Ty)
1784
+ if (!Ty || I. use_empty () )
1789
1785
return false ;
1790
1786
1791
1787
SmallVector<InstLane> Start (Ty->getNumElements ());
1792
1788
for (unsigned M = 0 , E = Ty->getNumElements (); M < E; ++M)
1793
- Start[M] = lookThroughShuffles (&I , M);
1789
+ Start[M] = lookThroughShuffles (&*I. use_begin () , M);
1794
1790
1795
1791
SmallVector<SmallVector<InstLane>> Worklist;
1796
1792
Worklist.push_back (Start);
1797
- SmallPtrSet<Value *, 4 > IdentityLeafs, SplatLeafs;
1793
+ SmallPtrSet<Use *, 4 > IdentityLeafs, SplatLeafs;
1798
1794
unsigned NumVisited = 0 ;
1799
1795
1800
1796
while (!Worklist.empty ()) {
1801
1797
if (++NumVisited > MaxInstrsToScan)
1802
1798
return false ;
1803
1799
1804
1800
SmallVector<InstLane> Item = Worklist.pop_back_val ();
1805
- auto [FrontV , FrontLane] = Item.front ();
1801
+ auto [FrontU , FrontLane] = Item.front ();
1806
1802
1807
1803
// If we found an undef first lane then bail out to keep things simple.
1808
- if (!FrontV )
1804
+ if (!FrontU )
1809
1805
return false ;
1810
1806
1811
1807
// Look for an identity value.
1812
- if (! FrontLane &&
1813
- cast<FixedVectorType>(FrontV ->getType ())->getNumElements () ==
1808
+ if (FrontLane == 0 &&
1809
+ cast<FixedVectorType>(FrontU-> get () ->getType ())->getNumElements () ==
1814
1810
Ty->getNumElements () &&
1815
1811
all_of (drop_begin (enumerate(Item)), [Item](const auto &E) {
1816
- Value *FrontV = Item.front ().first ;
1817
- return !E.value ().first || (E.value ().first == FrontV &&
1812
+ Value *FrontV = Item.front ().first -> get () ;
1813
+ return !E.value ().first || (E.value ().first -> get () == FrontV &&
1818
1814
E.value ().second == (int )E.index ());
1819
1815
})) {
1820
- IdentityLeafs.insert (FrontV );
1816
+ IdentityLeafs.insert (FrontU );
1821
1817
continue ;
1822
1818
}
1823
1819
// Look for constants, for the moment only supporting constant splats.
1824
- if (auto *C = dyn_cast<Constant>(FrontV );
1820
+ if (auto *C = dyn_cast<Constant>(FrontU );
1825
1821
C && C->getSplatValue () &&
1826
1822
all_of (drop_begin (Item), [Item](InstLane &IL) {
1827
- Value *FrontV = Item.front ().first ;
1828
- Value *V = IL.first ;
1829
- return !V || V == FrontV;
1823
+ Value *FrontV = Item.front ().first -> get () ;
1824
+ Use *U = IL.first ;
1825
+ return !U || U-> get () == FrontV;
1830
1826
})) {
1831
- SplatLeafs.insert (FrontV );
1827
+ SplatLeafs.insert (FrontU );
1832
1828
continue ;
1833
1829
}
1834
1830
// Look for a splat value.
1835
1831
if (all_of (drop_begin (Item), [Item](InstLane &IL) {
1836
- auto [FrontV , FrontLane] = Item.front ();
1837
- auto [V , Lane] = IL;
1838
- return !V || (V == FrontV && Lane == FrontLane);
1832
+ auto [FrontU , FrontLane] = Item.front ();
1833
+ auto [U , Lane] = IL;
1834
+ return !U || (U-> get () == FrontU-> get () && Lane == FrontLane);
1839
1835
})) {
1840
- SplatLeafs.insert (FrontV );
1836
+ SplatLeafs.insert (FrontU );
1841
1837
continue ;
1842
1838
}
1843
1839
1844
1840
// We need each element to be the same type of value, and check that each
1845
1841
// element has a single use.
1846
1842
if (!all_of (drop_begin (Item), [Item](InstLane IL) {
1847
- Value *FrontV = Item.front ().first ;
1848
- Value *V = IL.first ;
1849
- if (!V)
1843
+ Value *FrontV = Item.front ().first ->get ();
1844
+ if (!IL.first )
1850
1845
return true ;
1846
+ Value *V = IL.first ->get ();
1851
1847
if (auto *I = dyn_cast<Instruction>(V); I && !I->hasOneUse ())
1852
1848
return false ;
1853
1849
if (V->getValueID () != FrontV->getValueID ())
@@ -1869,25 +1865,25 @@ bool VectorCombine::foldShuffleToIdentity(Instruction &I) {
1869
1865
1870
1866
// Check the operator is one that we support. We exclude div/rem in case
1871
1867
// they hit UB from poison lanes.
1872
- if ((isa<BinaryOperator>(FrontV ) &&
1873
- !cast<BinaryOperator>(FrontV )->isIntDivRem ()) ||
1874
- isa<CmpInst>(FrontV )) {
1868
+ if ((isa<BinaryOperator>(FrontU ) &&
1869
+ !cast<BinaryOperator>(FrontU )->isIntDivRem ()) ||
1870
+ isa<CmpInst>(FrontU )) {
1875
1871
Worklist.push_back (generateInstLaneVectorFromOperand (Item, 0 ));
1876
1872
Worklist.push_back (generateInstLaneVectorFromOperand (Item, 1 ));
1877
- } else if (isa<UnaryOperator, TruncInst, ZExtInst, SExtInst>(FrontV )) {
1873
+ } else if (isa<UnaryOperator, TruncInst, ZExtInst, SExtInst>(FrontU )) {
1878
1874
Worklist.push_back (generateInstLaneVectorFromOperand (Item, 0 ));
1879
- } else if (isa<SelectInst>(FrontV )) {
1875
+ } else if (isa<SelectInst>(FrontU )) {
1880
1876
Worklist.push_back (generateInstLaneVectorFromOperand (Item, 0 ));
1881
1877
Worklist.push_back (generateInstLaneVectorFromOperand (Item, 1 ));
1882
1878
Worklist.push_back (generateInstLaneVectorFromOperand (Item, 2 ));
1883
- } else if (auto *II = dyn_cast<IntrinsicInst>(FrontV );
1879
+ } else if (auto *II = dyn_cast<IntrinsicInst>(FrontU );
1884
1880
II && isTriviallyVectorizable (II->getIntrinsicID ())) {
1885
1881
for (unsigned Op = 0 , E = II->getNumOperands () - 1 ; Op < E; Op++) {
1886
1882
if (isVectorIntrinsicWithScalarOpAtArg (II->getIntrinsicID (), Op)) {
1887
1883
if (!all_of (drop_begin (Item), [Item, Op](InstLane &IL) {
1888
- Value *FrontV = Item.front ().first ;
1889
- Value *V = IL.first ;
1890
- return !V || (cast<Instruction>(V )->getOperand (Op) ==
1884
+ Value *FrontV = Item.front ().first -> get () ;
1885
+ Use *U = IL.first ;
1886
+ return !U || (cast<Instruction>(U-> get () )->getOperand (Op) ==
1891
1887
cast<Instruction>(FrontV)->getOperand (Op));
1892
1888
}))
1893
1889
return false ;
0 commit comments