[mlir][VectorOps] Add conversion of 1-D vector.interleave ops to LLVM (#80966)
The 1-D case directly maps to LLVM intrinsics. The n-D case will be handled by unrolling to 1-D first (in a later patch). Depends on: #80965
This commit is contained in:
@@ -1734,6 +1734,45 @@ struct VectorSplatNdOpLowering : public ConvertOpToLLVMPattern<SplatOp> {
|
||||
}
|
||||
};
|
||||
|
||||
/// Conversion pattern for a `vector.interleave`.
|
||||
/// This supports fixed-sized vectors and scalable vectors.
|
||||
struct VectorInterleaveOpLowering
|
||||
: public ConvertOpToLLVMPattern<vector::InterleaveOp> {
|
||||
using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern;
|
||||
|
||||
LogicalResult
|
||||
matchAndRewrite(vector::InterleaveOp interleaveOp, OpAdaptor adaptor,
|
||||
ConversionPatternRewriter &rewriter) const override {
|
||||
VectorType resultType = interleaveOp.getResultVectorType();
|
||||
// n-D interleaves should have been lowered already.
|
||||
if (resultType.getRank() != 1)
|
||||
return rewriter.notifyMatchFailure(interleaveOp,
|
||||
"InterleaveOp not rank 1");
|
||||
// If the result is rank 1, then this directly maps to LLVM.
|
||||
if (resultType.isScalable()) {
|
||||
rewriter.replaceOpWithNewOp<LLVM::experimental_vector_interleave2>(
|
||||
interleaveOp, typeConverter->convertType(resultType),
|
||||
adaptor.getLhs(), adaptor.getRhs());
|
||||
return success();
|
||||
}
|
||||
// Lower fixed-size interleaves to a shufflevector. While the
|
||||
// vector.interleave2 intrinsic supports fixed and scalable vectors, the
|
||||
// langref still recommends fixed-vectors use shufflevector, see:
|
||||
// https://llvm.org/docs/LangRef.html#id876.
|
||||
int64_t resultVectorSize = resultType.getNumElements();
|
||||
SmallVector<int32_t> interleaveShuffleMask;
|
||||
interleaveShuffleMask.reserve(resultVectorSize);
|
||||
for (int i = 0, end = resultVectorSize / 2; i < end; ++i) {
|
||||
interleaveShuffleMask.push_back(i);
|
||||
interleaveShuffleMask.push_back((resultVectorSize / 2) + i);
|
||||
}
|
||||
rewriter.replaceOpWithNewOp<LLVM::ShuffleVectorOp>(
|
||||
interleaveOp, adaptor.getLhs(), adaptor.getRhs(),
|
||||
interleaveShuffleMask);
|
||||
return success();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
/// Populate the given list with patterns that convert from Vector to LLVM.
|
||||
@@ -1758,7 +1797,8 @@ void mlir::populateVectorToLLVMConversionPatterns(
|
||||
VectorExpandLoadOpConversion, VectorCompressStoreOpConversion,
|
||||
VectorSplatOpLowering, VectorSplatNdOpLowering,
|
||||
VectorScalableInsertOpLowering, VectorScalableExtractOpLowering,
|
||||
MaskedReductionOpConversion>(converter);
|
||||
MaskedReductionOpConversion, VectorInterleaveOpLowering>(
|
||||
converter);
|
||||
// Transfer ops with rank > 1 are handled by VectorToSCF.
|
||||
populateVectorTransferLoweringPatterns(patterns, /*maxTransferRank=*/1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user