199ef9eebSMatthias Springer //===- VectorInsertExtractStridedSliceRewritePatterns.cpp - Rewrites ------===//
299ef9eebSMatthias Springer //
399ef9eebSMatthias Springer // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
499ef9eebSMatthias Springer // See https://llvm.org/LICENSE.txt for license information.
599ef9eebSMatthias Springer // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
699ef9eebSMatthias Springer //
799ef9eebSMatthias Springer //===----------------------------------------------------------------------===//
899ef9eebSMatthias Springer 
9abc362a1SJakub Kuderski #include "mlir/Dialect/Arith/IR/Arith.h"
1099ef9eebSMatthias Springer #include "mlir/Dialect/MemRef/IR/MemRef.h"
1199ef9eebSMatthias Springer #include "mlir/Dialect/Utils/IndexingUtils.h"
1299ef9eebSMatthias Springer #include "mlir/Dialect/Vector/IR/VectorOps.h"
1399ef9eebSMatthias Springer #include "mlir/Dialect/Vector/Transforms/VectorRewritePatterns.h"
1499ef9eebSMatthias Springer #include "mlir/Dialect/Vector/Utils/VectorUtils.h"
1599ef9eebSMatthias Springer #include "mlir/IR/BuiltinTypes.h"
1639c80656SLei Zhang #include "mlir/IR/PatternMatch.h"
1799ef9eebSMatthias Springer 
1899ef9eebSMatthias Springer using namespace mlir;
1999ef9eebSMatthias Springer using namespace mlir::vector;
2099ef9eebSMatthias Springer 
2199ef9eebSMatthias Springer /// RewritePattern for InsertStridedSliceOp where source and destination vectors
2299ef9eebSMatthias Springer /// have different ranks.
2399ef9eebSMatthias Springer ///
2499ef9eebSMatthias Springer /// When ranks are different, InsertStridedSlice needs to extract a properly
2599ef9eebSMatthias Springer /// ranked vector from the destination vector into which to insert. This pattern
2699ef9eebSMatthias Springer /// only takes care of this extraction part and forwards the rest to
2759d3a9e0SLei Zhang /// [ConvertSameRankInsertStridedSliceIntoShuffle].
2899ef9eebSMatthias Springer ///
2999ef9eebSMatthias Springer /// For a k-D source and n-D destination vector (k < n), we emit:
3099ef9eebSMatthias Springer ///   1. ExtractOp to extract the (unique) (n-1)-D subvector into which to
3199ef9eebSMatthias Springer ///      insert the k-D source.
3299ef9eebSMatthias Springer ///   2. k-D -> (n-1)-D InsertStridedSlice op
3399ef9eebSMatthias Springer ///   3. InsertOp that is the reverse of 1.
3459d3a9e0SLei Zhang class DecomposeDifferentRankInsertStridedSlice
3599ef9eebSMatthias Springer     : public OpRewritePattern<InsertStridedSliceOp> {
3699ef9eebSMatthias Springer public:
3799ef9eebSMatthias Springer   using OpRewritePattern<InsertStridedSliceOp>::OpRewritePattern;
3899ef9eebSMatthias Springer 
3999ef9eebSMatthias Springer   LogicalResult matchAndRewrite(InsertStridedSliceOp op,
4099ef9eebSMatthias Springer                                 PatternRewriter &rewriter) const override {
4199ef9eebSMatthias Springer     auto srcType = op.getSourceVectorType();
4299ef9eebSMatthias Springer     auto dstType = op.getDestVectorType();
4399ef9eebSMatthias Springer 
447c38fd60SJacques Pienaar     if (op.getOffsets().getValue().empty())
4599ef9eebSMatthias Springer       return failure();
4699ef9eebSMatthias Springer 
4799ef9eebSMatthias Springer     auto loc = op.getLoc();
4899ef9eebSMatthias Springer     int64_t rankDiff = dstType.getRank() - srcType.getRank();
4999ef9eebSMatthias Springer     assert(rankDiff >= 0);
5099ef9eebSMatthias Springer     if (rankDiff == 0)
5199ef9eebSMatthias Springer       return failure();
5299ef9eebSMatthias Springer 
5399ef9eebSMatthias Springer     int64_t rankRest = dstType.getRank() - rankDiff;
5499ef9eebSMatthias Springer     // Extract / insert the subvector of matching rank and InsertStridedSlice
5599ef9eebSMatthias Springer     // on it.
567c38fd60SJacques Pienaar     Value extracted = rewriter.create<ExtractOp>(
577c38fd60SJacques Pienaar         loc, op.getDest(),
587c38fd60SJacques Pienaar         getI64SubArray(op.getOffsets(), /*dropFront=*/0,
5999ef9eebSMatthias Springer                        /*dropBack=*/rankRest));
6099ef9eebSMatthias Springer 
6199ef9eebSMatthias Springer     // A different pattern will kick in for InsertStridedSlice with matching
6299ef9eebSMatthias Springer     // ranks.
6399ef9eebSMatthias Springer     auto stridedSliceInnerOp = rewriter.create<InsertStridedSliceOp>(
647c38fd60SJacques Pienaar         loc, op.getSource(), extracted,
657c38fd60SJacques Pienaar         getI64SubArray(op.getOffsets(), /*dropFront=*/rankDiff),
667c38fd60SJacques Pienaar         getI64SubArray(op.getStrides(), /*dropFront=*/0));
6799ef9eebSMatthias Springer 
6899ef9eebSMatthias Springer     rewriter.replaceOpWithNewOp<InsertOp>(
697c38fd60SJacques Pienaar         op, stridedSliceInnerOp.getResult(), op.getDest(),
707c38fd60SJacques Pienaar         getI64SubArray(op.getOffsets(), /*dropFront=*/0,
7199ef9eebSMatthias Springer                        /*dropBack=*/rankRest));
7299ef9eebSMatthias Springer     return success();
7399ef9eebSMatthias Springer   }
7499ef9eebSMatthias Springer };
7599ef9eebSMatthias Springer 
7699ef9eebSMatthias Springer /// RewritePattern for InsertStridedSliceOp where source and destination vectors
7799ef9eebSMatthias Springer /// have the same rank. For each outermost index in the slice:
7899ef9eebSMatthias Springer ///   begin    end             stride
7999ef9eebSMatthias Springer /// [offset : offset+size*stride : stride]
8099ef9eebSMatthias Springer ///   1. ExtractOp one (k-1)-D source subvector and one (n-1)-D dest subvector.
8199ef9eebSMatthias Springer ///   2. InsertStridedSlice (k-1)-D into (n-1)-D
8299ef9eebSMatthias Springer ///   3. the destination subvector is inserted back in the proper place
8399ef9eebSMatthias Springer ///   3. InsertOp that is the reverse of 1.
8459d3a9e0SLei Zhang class ConvertSameRankInsertStridedSliceIntoShuffle
8599ef9eebSMatthias Springer     : public OpRewritePattern<InsertStridedSliceOp> {
8699ef9eebSMatthias Springer public:
8799ef9eebSMatthias Springer   using OpRewritePattern<InsertStridedSliceOp>::OpRewritePattern;
8899ef9eebSMatthias Springer 
8999ef9eebSMatthias Springer   void initialize() {
9099ef9eebSMatthias Springer     // This pattern creates recursive InsertStridedSliceOp, but the recursion is
9199ef9eebSMatthias Springer     // bounded as the rank is strictly decreasing.
9299ef9eebSMatthias Springer     setHasBoundedRewriteRecursion();
9399ef9eebSMatthias Springer   }
9499ef9eebSMatthias Springer 
9599ef9eebSMatthias Springer   LogicalResult matchAndRewrite(InsertStridedSliceOp op,
9699ef9eebSMatthias Springer                                 PatternRewriter &rewriter) const override {
9799ef9eebSMatthias Springer     auto srcType = op.getSourceVectorType();
9899ef9eebSMatthias Springer     auto dstType = op.getDestVectorType();
9999ef9eebSMatthias Springer 
1007c38fd60SJacques Pienaar     if (op.getOffsets().getValue().empty())
10199ef9eebSMatthias Springer       return failure();
10299ef9eebSMatthias Springer 
10399ef9eebSMatthias Springer     int64_t srcRank = srcType.getRank();
10499ef9eebSMatthias Springer     int64_t dstRank = dstType.getRank();
10599ef9eebSMatthias Springer     assert(dstRank >= srcRank);
10699ef9eebSMatthias Springer     if (dstRank != srcRank)
10799ef9eebSMatthias Springer       return failure();
10899ef9eebSMatthias Springer 
10999ef9eebSMatthias Springer     if (srcType == dstType) {
1107c38fd60SJacques Pienaar       rewriter.replaceOp(op, op.getSource());
11199ef9eebSMatthias Springer       return success();
11299ef9eebSMatthias Springer     }
11399ef9eebSMatthias Springer 
11499ef9eebSMatthias Springer     int64_t offset =
1155550c821STres Popp         cast<IntegerAttr>(op.getOffsets().getValue().front()).getInt();
11699ef9eebSMatthias Springer     int64_t size = srcType.getShape().front();
11799ef9eebSMatthias Springer     int64_t stride =
1185550c821STres Popp         cast<IntegerAttr>(op.getStrides().getValue().front()).getInt();
11999ef9eebSMatthias Springer 
12099ef9eebSMatthias Springer     auto loc = op.getLoc();
1217c38fd60SJacques Pienaar     Value res = op.getDest();
12299ef9eebSMatthias Springer 
12399ef9eebSMatthias Springer     if (srcRank == 1) {
12499ef9eebSMatthias Springer       int nSrc = srcType.getShape().front();
12599ef9eebSMatthias Springer       int nDest = dstType.getShape().front();
12699ef9eebSMatthias Springer       // 1. Scale source to destType so we can shufflevector them together.
12799ef9eebSMatthias Springer       SmallVector<int64_t> offsets(nDest, 0);
12899ef9eebSMatthias Springer       for (int64_t i = 0; i < nSrc; ++i)
12999ef9eebSMatthias Springer         offsets[i] = i;
1307c38fd60SJacques Pienaar       Value scaledSource = rewriter.create<ShuffleOp>(loc, op.getSource(),
1317c38fd60SJacques Pienaar                                                       op.getSource(), offsets);
13299ef9eebSMatthias Springer 
13399ef9eebSMatthias Springer       // 2. Create a mask where we take the value from scaledSource of dest
13499ef9eebSMatthias Springer       // depending on the offset.
13599ef9eebSMatthias Springer       offsets.clear();
13699ef9eebSMatthias Springer       for (int64_t i = 0, e = offset + size * stride; i < nDest; ++i) {
13799ef9eebSMatthias Springer         if (i < offset || i >= e || (i - offset) % stride != 0)
13899ef9eebSMatthias Springer           offsets.push_back(nDest + i);
13999ef9eebSMatthias Springer         else
14099ef9eebSMatthias Springer           offsets.push_back((i - offset) / stride);
14199ef9eebSMatthias Springer       }
14299ef9eebSMatthias Springer 
14399ef9eebSMatthias Springer       // 3. Replace with a ShuffleOp.
1447c38fd60SJacques Pienaar       rewriter.replaceOpWithNewOp<ShuffleOp>(op, scaledSource, op.getDest(),
14599ef9eebSMatthias Springer                                              offsets);
14699ef9eebSMatthias Springer 
14799ef9eebSMatthias Springer       return success();
14899ef9eebSMatthias Springer     }
14999ef9eebSMatthias Springer 
15099ef9eebSMatthias Springer     // For each slice of the source vector along the most major dimension.
15199ef9eebSMatthias Springer     for (int64_t off = offset, e = offset + size * stride, idx = 0; off < e;
15299ef9eebSMatthias Springer          off += stride, ++idx) {
15399ef9eebSMatthias Springer       // 1. extract the proper subvector (or element) from source
154*8e663039SKunwar Grover       Value extractedSource =
155*8e663039SKunwar Grover           rewriter.create<ExtractOp>(loc, op.getSource(), idx);
1565550c821STres Popp       if (isa<VectorType>(extractedSource.getType())) {
15799ef9eebSMatthias Springer         // 2. If we have a vector, extract the proper subvector from destination
15899ef9eebSMatthias Springer         // Otherwise we are at the element level and no need to recurse.
159*8e663039SKunwar Grover         Value extractedDest =
160*8e663039SKunwar Grover             rewriter.create<ExtractOp>(loc, op.getDest(), off);
16199ef9eebSMatthias Springer         // 3. Reduce the problem to lowering a new InsertStridedSlice op with
16299ef9eebSMatthias Springer         // smaller rank.
16399ef9eebSMatthias Springer         extractedSource = rewriter.create<InsertStridedSliceOp>(
16499ef9eebSMatthias Springer             loc, extractedSource, extractedDest,
1657c38fd60SJacques Pienaar             getI64SubArray(op.getOffsets(), /* dropFront=*/1),
1667c38fd60SJacques Pienaar             getI64SubArray(op.getStrides(), /* dropFront=*/1));
16799ef9eebSMatthias Springer       }
16899ef9eebSMatthias Springer       // 4. Insert the extractedSource into the res vector.
169*8e663039SKunwar Grover       res = rewriter.create<InsertOp>(loc, extractedSource, res, off);
17099ef9eebSMatthias Springer     }
17199ef9eebSMatthias Springer 
17299ef9eebSMatthias Springer     rewriter.replaceOp(op, res);
17399ef9eebSMatthias Springer     return success();
17499ef9eebSMatthias Springer   }
17599ef9eebSMatthias Springer };
17699ef9eebSMatthias Springer 
17759d3a9e0SLei Zhang /// RewritePattern for ExtractStridedSliceOp where source and destination
17859d3a9e0SLei Zhang /// vectors are 1-D. For such cases, we can lower it to a ShuffleOp.
17959d3a9e0SLei Zhang class Convert1DExtractStridedSliceIntoShuffle
18059d3a9e0SLei Zhang     : public OpRewritePattern<ExtractStridedSliceOp> {
18159d3a9e0SLei Zhang public:
18259d3a9e0SLei Zhang   using OpRewritePattern<ExtractStridedSliceOp>::OpRewritePattern;
18359d3a9e0SLei Zhang 
18459d3a9e0SLei Zhang   LogicalResult matchAndRewrite(ExtractStridedSliceOp op,
18559d3a9e0SLei Zhang                                 PatternRewriter &rewriter) const override {
18659d3a9e0SLei Zhang     auto dstType = op.getType();
18759d3a9e0SLei Zhang 
18859d3a9e0SLei Zhang     assert(!op.getOffsets().getValue().empty() && "Unexpected empty offsets");
18959d3a9e0SLei Zhang 
19059d3a9e0SLei Zhang     int64_t offset =
1915550c821STres Popp         cast<IntegerAttr>(op.getOffsets().getValue().front()).getInt();
1925550c821STres Popp     int64_t size = cast<IntegerAttr>(op.getSizes().getValue().front()).getInt();
19359d3a9e0SLei Zhang     int64_t stride =
1945550c821STres Popp         cast<IntegerAttr>(op.getStrides().getValue().front()).getInt();
19559d3a9e0SLei Zhang 
196e7f05526SBenjamin Kramer     assert(dstType.getElementType().isSignlessIntOrIndexOrFloat());
19759d3a9e0SLei Zhang 
19859d3a9e0SLei Zhang     // Single offset can be more efficiently shuffled.
19959d3a9e0SLei Zhang     if (op.getOffsets().getValue().size() != 1)
20059d3a9e0SLei Zhang       return failure();
20159d3a9e0SLei Zhang 
20259d3a9e0SLei Zhang     SmallVector<int64_t, 4> offsets;
20359d3a9e0SLei Zhang     offsets.reserve(size);
20459d3a9e0SLei Zhang     for (int64_t off = offset, e = offset + size * stride; off < e;
20559d3a9e0SLei Zhang          off += stride)
20659d3a9e0SLei Zhang       offsets.push_back(off);
20759d3a9e0SLei Zhang     rewriter.replaceOpWithNewOp<ShuffleOp>(op, dstType, op.getVector(),
208b4444dcaSBenjamin Maxwell                                            op.getVector(), offsets);
20959d3a9e0SLei Zhang     return success();
21059d3a9e0SLei Zhang   }
21159d3a9e0SLei Zhang };
21259d3a9e0SLei Zhang 
21339c80656SLei Zhang /// For a 1-D ExtractStridedSlice, breaks it down into a chain of Extract ops
21439c80656SLei Zhang /// to extract each element from the source, and then a chain of Insert ops
21539c80656SLei Zhang /// to insert to the target vector.
21639c80656SLei Zhang class Convert1DExtractStridedSliceIntoExtractInsertChain final
21739c80656SLei Zhang     : public OpRewritePattern<ExtractStridedSliceOp> {
21839c80656SLei Zhang public:
21939c80656SLei Zhang   Convert1DExtractStridedSliceIntoExtractInsertChain(
22039c80656SLei Zhang       MLIRContext *context,
22139c80656SLei Zhang       std::function<bool(ExtractStridedSliceOp)> controlFn,
22239c80656SLei Zhang       PatternBenefit benefit)
22339c80656SLei Zhang       : OpRewritePattern(context, benefit), controlFn(std::move(controlFn)) {}
22439c80656SLei Zhang 
22539c80656SLei Zhang   LogicalResult matchAndRewrite(ExtractStridedSliceOp op,
22639c80656SLei Zhang                                 PatternRewriter &rewriter) const override {
22739c80656SLei Zhang     if (controlFn && !controlFn(op))
22839c80656SLei Zhang       return failure();
22939c80656SLei Zhang 
23039c80656SLei Zhang     // Only handle 1-D cases.
23139c80656SLei Zhang     if (op.getOffsets().getValue().size() != 1)
23239c80656SLei Zhang       return failure();
23339c80656SLei Zhang 
23439c80656SLei Zhang     int64_t offset =
2355550c821STres Popp         cast<IntegerAttr>(op.getOffsets().getValue().front()).getInt();
2365550c821STres Popp     int64_t size = cast<IntegerAttr>(op.getSizes().getValue().front()).getInt();
23739c80656SLei Zhang     int64_t stride =
2385550c821STres Popp         cast<IntegerAttr>(op.getStrides().getValue().front()).getInt();
23939c80656SLei Zhang 
24039c80656SLei Zhang     Location loc = op.getLoc();
24139c80656SLei Zhang     SmallVector<Value> elements;
24239c80656SLei Zhang     elements.reserve(size);
24339c80656SLei Zhang     for (int64_t i = offset, e = offset + size * stride; i < e; i += stride)
24439c80656SLei Zhang       elements.push_back(rewriter.create<ExtractOp>(loc, op.getVector(), i));
24539c80656SLei Zhang 
24639c80656SLei Zhang     Value result = rewriter.create<arith::ConstantOp>(
24739c80656SLei Zhang         loc, rewriter.getZeroAttr(op.getType()));
24839c80656SLei Zhang     for (int64_t i = 0; i < size; ++i)
24939c80656SLei Zhang       result = rewriter.create<InsertOp>(loc, elements[i], result, i);
25039c80656SLei Zhang 
25139c80656SLei Zhang     rewriter.replaceOp(op, result);
25239c80656SLei Zhang     return success();
25339c80656SLei Zhang   }
25439c80656SLei Zhang 
25539c80656SLei Zhang private:
25639c80656SLei Zhang   std::function<bool(ExtractStridedSliceOp)> controlFn;
25739c80656SLei Zhang };
25839c80656SLei Zhang 
25959d3a9e0SLei Zhang /// RewritePattern for ExtractStridedSliceOp where the source vector is n-D.
260*8e663039SKunwar Grover /// For such cases, we can rewrite it to ExtractOp + lower rank
261*8e663039SKunwar Grover /// ExtractStridedSliceOp + InsertOp for the n-D case.
26259d3a9e0SLei Zhang class DecomposeNDExtractStridedSlice
26399ef9eebSMatthias Springer     : public OpRewritePattern<ExtractStridedSliceOp> {
26499ef9eebSMatthias Springer public:
26599ef9eebSMatthias Springer   using OpRewritePattern<ExtractStridedSliceOp>::OpRewritePattern;
26699ef9eebSMatthias Springer 
26799ef9eebSMatthias Springer   void initialize() {
26899ef9eebSMatthias Springer     // This pattern creates recursive ExtractStridedSliceOp, but the recursion
26999ef9eebSMatthias Springer     // is bounded as the rank is strictly decreasing.
27099ef9eebSMatthias Springer     setHasBoundedRewriteRecursion();
27199ef9eebSMatthias Springer   }
27299ef9eebSMatthias Springer 
27399ef9eebSMatthias Springer   LogicalResult matchAndRewrite(ExtractStridedSliceOp op,
27499ef9eebSMatthias Springer                                 PatternRewriter &rewriter) const override {
27599ef9eebSMatthias Springer     auto dstType = op.getType();
27699ef9eebSMatthias Springer 
2777c38fd60SJacques Pienaar     assert(!op.getOffsets().getValue().empty() && "Unexpected empty offsets");
27899ef9eebSMatthias Springer 
27999ef9eebSMatthias Springer     int64_t offset =
2805550c821STres Popp         cast<IntegerAttr>(op.getOffsets().getValue().front()).getInt();
2815550c821STres Popp     int64_t size = cast<IntegerAttr>(op.getSizes().getValue().front()).getInt();
28299ef9eebSMatthias Springer     int64_t stride =
2835550c821STres Popp         cast<IntegerAttr>(op.getStrides().getValue().front()).getInt();
28499ef9eebSMatthias Springer 
2851acba8a4SBill Wendling     auto loc = op.getLoc();
28699ef9eebSMatthias Springer     auto elemType = dstType.getElementType();
28799ef9eebSMatthias Springer     assert(elemType.isSignlessIntOrIndexOrFloat());
28899ef9eebSMatthias Springer 
28959d3a9e0SLei Zhang     // Single offset can be more efficiently shuffled. It's handled in
29059d3a9e0SLei Zhang     // Convert1DExtractStridedSliceIntoShuffle.
29159d3a9e0SLei Zhang     if (op.getOffsets().getValue().size() == 1)
29259d3a9e0SLei Zhang       return failure();
29399ef9eebSMatthias Springer 
29499ef9eebSMatthias Springer     // Extract/insert on a lower ranked extract strided slice op.
29599ef9eebSMatthias Springer     Value zero = rewriter.create<arith::ConstantOp>(
29699ef9eebSMatthias Springer         loc, elemType, rewriter.getZeroAttr(elemType));
29799ef9eebSMatthias Springer     Value res = rewriter.create<SplatOp>(loc, dstType, zero);
29899ef9eebSMatthias Springer     for (int64_t off = offset, e = offset + size * stride, idx = 0; off < e;
29999ef9eebSMatthias Springer          off += stride, ++idx) {
300*8e663039SKunwar Grover       Value one = rewriter.create<ExtractOp>(loc, op.getVector(), off);
30199ef9eebSMatthias Springer       Value extracted = rewriter.create<ExtractStridedSliceOp>(
3027c38fd60SJacques Pienaar           loc, one, getI64SubArray(op.getOffsets(), /* dropFront=*/1),
3037c38fd60SJacques Pienaar           getI64SubArray(op.getSizes(), /* dropFront=*/1),
3047c38fd60SJacques Pienaar           getI64SubArray(op.getStrides(), /* dropFront=*/1));
305*8e663039SKunwar Grover       res = rewriter.create<InsertOp>(loc, extracted, res, idx);
30699ef9eebSMatthias Springer     }
30799ef9eebSMatthias Springer     rewriter.replaceOp(op, res);
30899ef9eebSMatthias Springer     return success();
30999ef9eebSMatthias Springer   }
31099ef9eebSMatthias Springer };
31199ef9eebSMatthias Springer 
31239c80656SLei Zhang void vector::populateVectorInsertExtractStridedSliceDecompositionPatterns(
31327cc31b6SNicolas Vasilache     RewritePatternSet &patterns, PatternBenefit benefit) {
31459d3a9e0SLei Zhang   patterns.add<DecomposeDifferentRankInsertStridedSlice,
31527cc31b6SNicolas Vasilache                DecomposeNDExtractStridedSlice>(patterns.getContext(), benefit);
31659d3a9e0SLei Zhang }
31759d3a9e0SLei Zhang 
31839c80656SLei Zhang void vector::populateVectorExtractStridedSliceToExtractInsertChainPatterns(
31939c80656SLei Zhang     RewritePatternSet &patterns,
32039c80656SLei Zhang     std::function<bool(ExtractStridedSliceOp)> controlFn,
32139c80656SLei Zhang     PatternBenefit benefit) {
32239c80656SLei Zhang   patterns.add<Convert1DExtractStridedSliceIntoExtractInsertChain>(
32339c80656SLei Zhang       patterns.getContext(), std::move(controlFn), benefit);
32439c80656SLei Zhang }
32539c80656SLei Zhang 
32699ef9eebSMatthias Springer /// Populate the given list with patterns that convert from Vector to LLVM.
32739c80656SLei Zhang void vector::populateVectorInsertExtractStridedSliceTransforms(
32827cc31b6SNicolas Vasilache     RewritePatternSet &patterns, PatternBenefit benefit) {
32927cc31b6SNicolas Vasilache   populateVectorInsertExtractStridedSliceDecompositionPatterns(patterns,
33027cc31b6SNicolas Vasilache                                                                benefit);
33159d3a9e0SLei Zhang   patterns.add<ConvertSameRankInsertStridedSliceIntoShuffle,
33227cc31b6SNicolas Vasilache                Convert1DExtractStridedSliceIntoShuffle>(patterns.getContext(),
33327cc31b6SNicolas Vasilache                                                         benefit);
33499ef9eebSMatthias Springer }
335