mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-28 03:46:06 +00:00
[mlir][vector] Add Vector-dialect interleave-to-shuffle pattern, enable in VectorToSPIRV (#91800)
Context: https://github.com/iree-org/iree/issues/17346. Test IREE integrate showing it's fixing the problem it's intended to fix, i.e. it allows IREE to drop its local revert of https://github.com/llvm/llvm-project/pull/89131: https://github.com/iree-org/iree/pull/17359 This is added to VectorToSPIRV because SPIRV doesn't currently handle `vector.interleave` (see motivating context above). This is limited to 1D, non-scalable vectors.
This commit is contained in:
parent
ad727b1a67
commit
cf40c93b5b
@ -306,6 +306,20 @@ def ApplyLowerInterleavePatternsOp : Op<Transform_Dialect,
|
||||
let assemblyFormat = "attr-dict";
|
||||
}
|
||||
|
||||
def ApplyInterleaveToShufflePatternsOp : Op<Transform_Dialect,
|
||||
"apply_patterns.vector.interleave_to_shuffle",
|
||||
[DeclareOpInterfaceMethods<PatternDescriptorOpInterface>]> {
|
||||
let description = [{
|
||||
Indicates that 1D vector interleave operations should be rewritten as
|
||||
vector shuffle operations.
|
||||
|
||||
This is motivated by some current codegen backends not handling vector
|
||||
interleave operations.
|
||||
}];
|
||||
|
||||
let assemblyFormat = "attr-dict";
|
||||
}
|
||||
|
||||
def ApplyRewriteNarrowTypePatternsOp : Op<Transform_Dialect,
|
||||
"apply_patterns.vector.rewrite_narrow_types",
|
||||
[DeclareOpInterfaceMethods<PatternDescriptorOpInterface>]> {
|
||||
|
@ -273,6 +273,9 @@ void populateVectorInterleaveLoweringPatterns(RewritePatternSet &patterns,
|
||||
int64_t targetRank = 1,
|
||||
PatternBenefit benefit = 1);
|
||||
|
||||
void populateVectorInterleaveToShufflePatterns(RewritePatternSet &patterns,
|
||||
PatternBenefit benefit = 1);
|
||||
|
||||
} // namespace vector
|
||||
} // namespace mlir
|
||||
#endif // MLIR_DIALECT_VECTOR_TRANSFORMS_LOWERINGPATTERNS_H
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "mlir/Dialect/SPIRV/IR/SPIRVTypes.h"
|
||||
#include "mlir/Dialect/SPIRV/Transforms/SPIRVConversion.h"
|
||||
#include "mlir/Dialect/Vector/IR/VectorOps.h"
|
||||
#include "mlir/Dialect/Vector/Transforms/LoweringPatterns.h"
|
||||
#include "mlir/IR/Attributes.h"
|
||||
#include "mlir/IR/BuiltinAttributes.h"
|
||||
#include "mlir/IR/BuiltinTypes.h"
|
||||
@ -828,6 +829,9 @@ void mlir::populateVectorToSPIRVPatterns(SPIRVTypeConverter &typeConverter,
|
||||
// than the generic one that extracts all elements.
|
||||
patterns.add<VectorReductionToFPDotProd>(typeConverter, patterns.getContext(),
|
||||
PatternBenefit(2));
|
||||
|
||||
// Need this until vector.interleave is handled.
|
||||
vector::populateVectorInterleaveToShufflePatterns(patterns);
|
||||
}
|
||||
|
||||
void mlir::populateVectorReductionToSPIRVDotProductPatterns(
|
||||
|
@ -164,6 +164,11 @@ void transform::ApplyLowerInterleavePatternsOp::populatePatterns(
|
||||
vector::populateVectorInterleaveLoweringPatterns(patterns);
|
||||
}
|
||||
|
||||
void transform::ApplyInterleaveToShufflePatternsOp::populatePatterns(
|
||||
RewritePatternSet &patterns) {
|
||||
vector::populateVectorInterleaveToShufflePatterns(patterns);
|
||||
}
|
||||
|
||||
void transform::ApplyRewriteNarrowTypePatternsOp::populatePatterns(
|
||||
RewritePatternSet &patterns) {
|
||||
populateVectorNarrowTypeRewritePatterns(patterns);
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "mlir/Dialect/Vector/Utils/VectorUtils.h"
|
||||
#include "mlir/IR/BuiltinTypes.h"
|
||||
#include "mlir/IR/PatternMatch.h"
|
||||
#include "mlir/Support/LogicalResult.h"
|
||||
|
||||
#define DEBUG_TYPE "vector-interleave-lowering"
|
||||
|
||||
@ -77,9 +78,49 @@ private:
|
||||
int64_t targetRank = 1;
|
||||
};
|
||||
|
||||
/// Rewrite vector.interleave op into an equivalent vector.shuffle op, when
|
||||
/// applicable: `sourceType` must be 1D and non-scalable.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```mlir
|
||||
/// vector.interleave %a, %b : vector<7xi16>
|
||||
/// ```
|
||||
///
|
||||
/// Is rewritten into:
|
||||
///
|
||||
/// ```mlir
|
||||
/// vector.shuffle %arg0, %arg1 [0, 7, 1, 8, 2, 9, 3, 10, 4, 11, 5, 12, 6, 13]
|
||||
/// : vector<7xi16>, vector<7xi16>
|
||||
/// ```
|
||||
class InterleaveToShuffle : public OpRewritePattern<vector::InterleaveOp> {
|
||||
public:
|
||||
InterleaveToShuffle(MLIRContext *context, PatternBenefit benefit = 1)
|
||||
: OpRewritePattern(context, benefit) {};
|
||||
|
||||
LogicalResult matchAndRewrite(vector::InterleaveOp op,
|
||||
PatternRewriter &rewriter) const override {
|
||||
VectorType sourceType = op.getSourceVectorType();
|
||||
if (sourceType.getRank() != 1 || sourceType.isScalable()) {
|
||||
return failure();
|
||||
}
|
||||
int64_t n = sourceType.getNumElements();
|
||||
auto seq = llvm::seq<int64_t>(2 * n);
|
||||
auto zip = llvm::to_vector(llvm::map_range(
|
||||
seq, [n](int64_t i) { return (i % 2 ? n : 0) + i / 2; }));
|
||||
rewriter.replaceOpWithNewOp<ShuffleOp>(op, op.getLhs(), op.getRhs(), zip);
|
||||
return success();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
void mlir::vector::populateVectorInterleaveLoweringPatterns(
|
||||
RewritePatternSet &patterns, int64_t targetRank, PatternBenefit benefit) {
|
||||
patterns.add<UnrollInterleaveOp>(targetRank, patterns.getContext(), benefit);
|
||||
}
|
||||
|
||||
void mlir::vector::populateVectorInterleaveToShufflePatterns(
|
||||
RewritePatternSet &patterns, PatternBenefit benefit) {
|
||||
patterns.add<InterleaveToShuffle>(patterns.getContext(), benefit);
|
||||
}
|
||||
|
21
mlir/test/Dialect/Vector/vector-interleave-to-shuffle.mlir
Normal file
21
mlir/test/Dialect/Vector/vector-interleave-to-shuffle.mlir
Normal file
@ -0,0 +1,21 @@
|
||||
// RUN: mlir-opt %s --transform-interpreter | FileCheck %s
|
||||
|
||||
// CHECK-LABEL: @vector_interleave_to_shuffle
|
||||
func.func @vector_interleave_to_shuffle(%a: vector<7xi16>, %b: vector<7xi16>) -> vector<14xi16>
|
||||
{
|
||||
%0 = vector.interleave %a, %b : vector<7xi16>
|
||||
return %0 : vector<14xi16>
|
||||
}
|
||||
// CHECK: vector.shuffle %arg0, %arg1 [0, 7, 1, 8, 2, 9, 3, 10, 4, 11, 5, 12, 6, 13] : vector<7xi16>, vector<7xi16>
|
||||
|
||||
module attributes {transform.with_named_sequence} {
|
||||
transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {
|
||||
%f = transform.structured.match ops{["func.func"]} in %module_op
|
||||
: (!transform.any_op) -> !transform.any_op
|
||||
|
||||
transform.apply_patterns to %f {
|
||||
transform.apply_patterns.vector.interleave_to_shuffle
|
||||
} : !transform.any_op
|
||||
transform.yield
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user