@@ -1761,6 +1761,70 @@ struct VectorInterleaveOpLowering
1761
1761
}
1762
1762
};
1763
1763
1764
+ // / Conversion pattern for a `vector.deinterleave`.
1765
+ // / This supports for fixed-sized vectors and scalable vectors.
1766
+ struct VectorDeinterleaveOpLowering
1767
+ : public ConvertOpToLLVMPattern<vector::DeinterleaveOp> {
1768
+ using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern;
1769
+
1770
+ LogicalResult
1771
+ matchAndRewrite (vector::DeinterleaveOp deinterleaveOp, OpAdaptor adaptor,
1772
+ ConversionPatternRewriter &rewriter) const override {
1773
+ VectorType resultType = deinterleaveOp.getResultVectorType ();
1774
+ VectorType sourceType = deinterleaveOp.getSourceVectorType ();
1775
+ auto loc = deinterleaveOp.getLoc ();
1776
+
1777
+ // n-D deinterleave should be lowered to the 1-D lowering process.
1778
+ if (resultType.getRank () != 1 )
1779
+ return rewriter.notifyMatchFailure (deinterleaveOp,
1780
+ " DeinterleaveOp not rank 1" );
1781
+
1782
+ if (resultType.isScalable ()) {
1783
+ auto llvmTypeConverter = this ->getTypeConverter ();
1784
+ auto deinterleaveResults = deinterleaveOp.getResultTypes ();
1785
+ auto packedOpResults =
1786
+ llvmTypeConverter->packOperationResults (deinterleaveResults);
1787
+ auto intrinsic = rewriter.create <LLVM::vector_deinterleave2>(
1788
+ loc, packedOpResults, adaptor.getSource ());
1789
+
1790
+ auto evenResult = rewriter.create <LLVM::ExtractValueOp>(
1791
+ loc, intrinsic->getResult (0 ), 0 );
1792
+ auto oddResult = rewriter.create <LLVM::ExtractValueOp>(
1793
+ loc, intrinsic->getResult (0 ), 1 );
1794
+
1795
+ rewriter.replaceOp (deinterleaveOp, ValueRange{evenResult, oddResult});
1796
+ return success ();
1797
+ }
1798
+
1799
+ int64_t resultVectorSize = resultType.getNumElements ();
1800
+ SmallVector<int32_t > evenShuffleMask;
1801
+ SmallVector<int32_t > oddShuffleMask;
1802
+
1803
+ evenShuffleMask.reserve (resultVectorSize);
1804
+ oddShuffleMask.reserve (resultVectorSize);
1805
+
1806
+ for (int i = 0 ; i < sourceType.getNumElements (); ++i) {
1807
+ if (i % 2 == 0 )
1808
+ evenShuffleMask.push_back (i);
1809
+ else
1810
+ oddShuffleMask.push_back (i);
1811
+ }
1812
+
1813
+ // Fixed size deinterleave lowers to a shufflevector for
1814
+ // optimisation purposes. Whilst scalable sized vectors
1815
+ // are lowered to an LLVM intrinsic. See the language ref
1816
+ // for more details.
1817
+ auto poison = rewriter.create <LLVM::PoisonOp>(loc, sourceType);
1818
+ auto evenShuffle = rewriter.create <LLVM::ShuffleVectorOp>(
1819
+ loc, adaptor.getSource (), poison, evenShuffleMask);
1820
+ auto oddShuffle = rewriter.create <LLVM::ShuffleVectorOp>(
1821
+ loc, adaptor.getSource (), poison, oddShuffleMask);
1822
+
1823
+ rewriter.replaceOp (deinterleaveOp, ValueRange{evenShuffle, oddShuffle});
1824
+ return success ();
1825
+ }
1826
+ };
1827
+
1764
1828
} // namespace
1765
1829
1766
1830
// / Populate the given list with patterns that convert from Vector to LLVM.
@@ -1785,8 +1849,8 @@ void mlir::populateVectorToLLVMConversionPatterns(
1785
1849
VectorExpandLoadOpConversion, VectorCompressStoreOpConversion,
1786
1850
VectorSplatOpLowering, VectorSplatNdOpLowering,
1787
1851
VectorScalableInsertOpLowering, VectorScalableExtractOpLowering,
1788
- MaskedReductionOpConversion, VectorInterleaveOpLowering>(
1789
- converter);
1852
+ MaskedReductionOpConversion, VectorInterleaveOpLowering,
1853
+ VectorDeinterleaveOpLowering>( converter);
1790
1854
// Transfer ops with rank > 1 are handled by VectorToSCF.
1791
1855
populateVectorTransferLoweringPatterns (patterns, /* maxTransferRank=*/ 1 );
1792
1856
}
0 commit comments