@@ -1734,6 +1734,45 @@ struct VectorSplatNdOpLowering : public ConvertOpToLLVMPattern<SplatOp> {
17341734 }
17351735};
17361736
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+
17371776} // namespace
17381777
17391778// / Populate the given list with patterns that convert from Vector to LLVM.
@@ -1758,7 +1797,8 @@ void mlir::populateVectorToLLVMConversionPatterns(
17581797 VectorExpandLoadOpConversion, VectorCompressStoreOpConversion,
17591798 VectorSplatOpLowering, VectorSplatNdOpLowering,
17601799 VectorScalableInsertOpLowering, VectorScalableExtractOpLowering,
1761- MaskedReductionOpConversion>(converter);
1800+ MaskedReductionOpConversion, VectorInterleaveOpLowering>(
1801+ converter);
17621802 // Transfer ops with rank > 1 are handled by VectorToSCF.
17631803 populateVectorTransferLoweringPatterns (patterns, /* maxTransferRank=*/ 1 );
17641804}
0 commit comments