@@ -1734,6 +1734,44 @@ 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 failure ();
1750+ // If the result is rank 1, then this directly maps to LLVM.
1751+ if (resultType.isScalable ()) {
1752+ rewriter.replaceOpWithNewOp <LLVM::experimental_vector_interleave2>(
1753+ interleaveOp, typeConverter->convertType (resultType),
1754+ adaptor.getLhs (), adaptor.getRhs ());
1755+ return success ();
1756+ }
1757+ // Lower fixed-size interleaves to a shufflevector. While the
1758+ // vector.interleave2 intrinsic supports fixed and scalable vectors, the
1759+ // langref still recommends fixed-vectors use shufflevector, see:
1760+ // https://llvm.org/docs/LangRef.html#id876.
1761+ int64_t resultVectorSize = resultType.getNumElements ();
1762+ SmallVector<int32_t > interleaveShuffleMask;
1763+ interleaveShuffleMask.reserve (resultVectorSize);
1764+ for (int i = 0 , end = resultVectorSize / 2 ; i < end; ++i) {
1765+ interleaveShuffleMask.push_back (i);
1766+ interleaveShuffleMask.push_back ((resultVectorSize / 2 ) + i);
1767+ }
1768+ rewriter.replaceOpWithNewOp <LLVM::ShuffleVectorOp>(
1769+ interleaveOp, adaptor.getLhs (), adaptor.getRhs (),
1770+ interleaveShuffleMask);
1771+ return success ();
1772+ }
1773+ };
1774+
17371775} // namespace
17381776
17391777// / Populate the given list with patterns that convert from Vector to LLVM.
@@ -1758,7 +1796,8 @@ void mlir::populateVectorToLLVMConversionPatterns(
17581796 VectorExpandLoadOpConversion, VectorCompressStoreOpConversion,
17591797 VectorSplatOpLowering, VectorSplatNdOpLowering,
17601798 VectorScalableInsertOpLowering, VectorScalableExtractOpLowering,
1761- MaskedReductionOpConversion>(converter);
1799+ MaskedReductionOpConversion, VectorInterleaveOpLowering>(
1800+ converter);
17621801 // Transfer ops with rank > 1 are handled by VectorToSCF.
17631802 populateVectorTransferLoweringPatterns (patterns, /* maxTransferRank=*/ 1 );
17641803}
0 commit comments