@@ -1734,6 +1734,45 @@ struct VectorSplatNdOpLowering : public ConvertOpToLLVMPattern<SplatOp> {
1734
1734
}
1735
1735
};
1736
1736
1737
+ // / Conversion pattern for a `vector.interleave`.
1738
+ // / This supports fixed-sized vectors and scalable vectors.
1739
+ struct VectorInterleaveOpLowering
1740
+ : public ConvertOpToLLVMPattern<vector::InterleaveOp> {
1741
+ using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern;
1742
+
1743
+ LogicalResult
1744
+ matchAndRewrite (vector::InterleaveOp interleaveOp, OpAdaptor adaptor,
1745
+ ConversionPatternRewriter &rewriter) const override {
1746
+ VectorType resultType = interleaveOp.getResultVectorType ();
1747
+ // n-D interleaves should have been lowered already.
1748
+ if (resultType.getRank () != 1 )
1749
+ return rewriter.notifyMatchFailure (interleaveOp,
1750
+ " InterleaveOp not rank 1" );
1751
+ // If the result is rank 1, then this directly maps to LLVM.
1752
+ if (resultType.isScalable ()) {
1753
+ rewriter.replaceOpWithNewOp <LLVM::experimental_vector_interleave2>(
1754
+ interleaveOp, typeConverter->convertType (resultType),
1755
+ adaptor.getLhs (), adaptor.getRhs ());
1756
+ return success ();
1757
+ }
1758
+ // Lower fixed-size interleaves to a shufflevector. While the
1759
+ // vector.interleave2 intrinsic supports fixed and scalable vectors, the
1760
+ // langref still recommends fixed-vectors use shufflevector, see:
1761
+ // https://llvm.org/docs/LangRef.html#id876.
1762
+ int64_t resultVectorSize = resultType.getNumElements ();
1763
+ SmallVector<int32_t > interleaveShuffleMask;
1764
+ interleaveShuffleMask.reserve (resultVectorSize);
1765
+ for (int i = 0 , end = resultVectorSize / 2 ; i < end; ++i) {
1766
+ interleaveShuffleMask.push_back (i);
1767
+ interleaveShuffleMask.push_back ((resultVectorSize / 2 ) + i);
1768
+ }
1769
+ rewriter.replaceOpWithNewOp <LLVM::ShuffleVectorOp>(
1770
+ interleaveOp, adaptor.getLhs (), adaptor.getRhs (),
1771
+ interleaveShuffleMask);
1772
+ return success ();
1773
+ }
1774
+ };
1775
+
1737
1776
} // namespace
1738
1777
1739
1778
// / Populate the given list with patterns that convert from Vector to LLVM.
@@ -1758,7 +1797,8 @@ void mlir::populateVectorToLLVMConversionPatterns(
1758
1797
VectorExpandLoadOpConversion, VectorCompressStoreOpConversion,
1759
1798
VectorSplatOpLowering, VectorSplatNdOpLowering,
1760
1799
VectorScalableInsertOpLowering, VectorScalableExtractOpLowering,
1761
- MaskedReductionOpConversion>(converter);
1800
+ MaskedReductionOpConversion, VectorInterleaveOpLowering>(
1801
+ converter);
1762
1802
// Transfer ops with rank > 1 are handled by VectorToSCF.
1763
1803
populateVectorTransferLoweringPatterns (patterns, /* maxTransferRank=*/ 1 );
1764
1804
}
0 commit comments