1fec6c5acSUday Bondhugula //===- TestPatterns.cpp - Test dialect pattern driver ---------------------===//
2fec6c5acSUday Bondhugula //
3fec6c5acSUday Bondhugula // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fec6c5acSUday Bondhugula // See https://llvm.org/LICENSE.txt for license information.
5fec6c5acSUday Bondhugula // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fec6c5acSUday Bondhugula //
7fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
8fec6c5acSUday Bondhugula 
9fec6c5acSUday Bondhugula #include "TestDialect.h"
10fec6c5acSUday Bondhugula #include "mlir/Conversion/StandardToStandard/StandardToStandard.h"
11fec6c5acSUday Bondhugula #include "mlir/IR/PatternMatch.h"
12fec6c5acSUday Bondhugula #include "mlir/Pass/Pass.h"
13fec6c5acSUday Bondhugula #include "mlir/Transforms/DialectConversion.h"
149ba37b3bSJacques Pienaar 
15fec6c5acSUday Bondhugula using namespace mlir;
16fec6c5acSUday Bondhugula 
17fec6c5acSUday Bondhugula // Native function for testing NativeCodeCall
18fec6c5acSUday Bondhugula static Value chooseOperand(Value input1, Value input2, BoolAttr choice) {
19fec6c5acSUday Bondhugula   return choice.getValue() ? input1 : input2;
20fec6c5acSUday Bondhugula }
21fec6c5acSUday Bondhugula 
22fec6c5acSUday Bondhugula static void createOpI(PatternRewriter &rewriter, Value input) {
23fec6c5acSUday Bondhugula   rewriter.create<OpI>(rewriter.getUnknownLoc(), input);
24fec6c5acSUday Bondhugula }
25fec6c5acSUday Bondhugula 
26fec6c5acSUday Bondhugula static void handleNoResultOp(PatternRewriter &rewriter,
27fec6c5acSUday Bondhugula                              OpSymbolBindingNoResult op) {
28fec6c5acSUday Bondhugula   // Turn the no result op to a one-result op.
29fec6c5acSUday Bondhugula   rewriter.create<OpSymbolBindingB>(op.getLoc(), op.operand().getType(),
30fec6c5acSUday Bondhugula                                     op.operand());
31fec6c5acSUday Bondhugula }
32fec6c5acSUday Bondhugula 
33fec6c5acSUday Bondhugula namespace {
34fec6c5acSUday Bondhugula #include "TestPatterns.inc"
35fec6c5acSUday Bondhugula } // end anonymous namespace
36fec6c5acSUday Bondhugula 
37fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
38fec6c5acSUday Bondhugula // Canonicalizer Driver.
39fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
40fec6c5acSUday Bondhugula 
41fec6c5acSUday Bondhugula namespace {
4280aca1eaSRiver Riddle struct TestPatternDriver : public PassWrapper<TestPatternDriver, FunctionPass> {
43fec6c5acSUday Bondhugula   void runOnFunction() override {
44fec6c5acSUday Bondhugula     mlir::OwningRewritePatternList patterns;
45fec6c5acSUday Bondhugula     populateWithGenerated(&getContext(), &patterns);
46fec6c5acSUday Bondhugula 
47fec6c5acSUday Bondhugula     // Verify named pattern is generated with expected name.
48fec6c5acSUday Bondhugula     patterns.insert<TestNamedPatternRule>(&getContext());
49fec6c5acSUday Bondhugula 
50a5b9316bSUday Bondhugula     applyPatternsAndFoldGreedily(getFunction(), patterns);
51fec6c5acSUday Bondhugula   }
52fec6c5acSUday Bondhugula };
53fec6c5acSUday Bondhugula } // end anonymous namespace
54fec6c5acSUday Bondhugula 
55fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
56fec6c5acSUday Bondhugula // ReturnType Driver.
57fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
58fec6c5acSUday Bondhugula 
59fec6c5acSUday Bondhugula namespace {
60fec6c5acSUday Bondhugula // Generate ops for each instance where the type can be successfully inferred.
61fec6c5acSUday Bondhugula template <typename OpTy>
62fec6c5acSUday Bondhugula static void invokeCreateWithInferredReturnType(Operation *op) {
63fec6c5acSUday Bondhugula   auto *context = op->getContext();
64fec6c5acSUday Bondhugula   auto fop = op->getParentOfType<FuncOp>();
65fec6c5acSUday Bondhugula   auto location = UnknownLoc::get(context);
66fec6c5acSUday Bondhugula   OpBuilder b(op);
67fec6c5acSUday Bondhugula   b.setInsertionPointAfter(op);
68fec6c5acSUday Bondhugula 
69fec6c5acSUday Bondhugula   // Use permutations of 2 args as operands.
70fec6c5acSUday Bondhugula   assert(fop.getNumArguments() >= 2);
71fec6c5acSUday Bondhugula   for (int i = 0, e = fop.getNumArguments(); i < e; ++i) {
72fec6c5acSUday Bondhugula     for (int j = 0; j < e; ++j) {
73fec6c5acSUday Bondhugula       std::array<Value, 2> values = {{fop.getArgument(i), fop.getArgument(j)}};
74fec6c5acSUday Bondhugula       SmallVector<Type, 2> inferredReturnTypes;
75fec6c5acSUday Bondhugula       if (succeeded(OpTy::inferReturnTypes(context, llvm::None, values,
76fec6c5acSUday Bondhugula                                            op->getAttrs(), op->getRegions(),
77fec6c5acSUday Bondhugula                                            inferredReturnTypes))) {
78fec6c5acSUday Bondhugula         OperationState state(location, OpTy::getOperationName());
79fec6c5acSUday Bondhugula         // TODO(jpienaar): Expand to regions.
80*bb1d976fSAlex Zinenko         OpTy::build(b, state, values, op->getAttrs());
81fec6c5acSUday Bondhugula         (void)b.createOperation(state);
82fec6c5acSUday Bondhugula       }
83fec6c5acSUday Bondhugula     }
84fec6c5acSUday Bondhugula   }
85fec6c5acSUday Bondhugula }
86fec6c5acSUday Bondhugula 
87fec6c5acSUday Bondhugula static void reifyReturnShape(Operation *op) {
88fec6c5acSUday Bondhugula   OpBuilder b(op);
89fec6c5acSUday Bondhugula 
90fec6c5acSUday Bondhugula   // Use permutations of 2 args as operands.
91fec6c5acSUday Bondhugula   auto shapedOp = cast<OpWithShapedTypeInferTypeInterfaceOp>(op);
92fec6c5acSUday Bondhugula   SmallVector<Value, 2> shapes;
93fec6c5acSUday Bondhugula   if (failed(shapedOp.reifyReturnTypeShapes(b, shapes)))
94fec6c5acSUday Bondhugula     return;
95fec6c5acSUday Bondhugula   for (auto it : llvm::enumerate(shapes))
96fec6c5acSUday Bondhugula     op->emitRemark() << "value " << it.index() << ": "
97fec6c5acSUday Bondhugula                      << it.value().getDefiningOp();
98fec6c5acSUday Bondhugula }
99fec6c5acSUday Bondhugula 
10080aca1eaSRiver Riddle struct TestReturnTypeDriver
10180aca1eaSRiver Riddle     : public PassWrapper<TestReturnTypeDriver, FunctionPass> {
102fec6c5acSUday Bondhugula   void runOnFunction() override {
103fec6c5acSUday Bondhugula     if (getFunction().getName() == "testCreateFunctions") {
104fec6c5acSUday Bondhugula       std::vector<Operation *> ops;
105fec6c5acSUday Bondhugula       // Collect ops to avoid triggering on inserted ops.
106fec6c5acSUday Bondhugula       for (auto &op : getFunction().getBody().front())
107fec6c5acSUday Bondhugula         ops.push_back(&op);
108fec6c5acSUday Bondhugula       // Generate test patterns for each, but skip terminator.
109fec6c5acSUday Bondhugula       for (auto *op : llvm::makeArrayRef(ops).drop_back()) {
110fec6c5acSUday Bondhugula         // Test create method of each of the Op classes below. The resultant
111fec6c5acSUday Bondhugula         // output would be in reverse order underneath `op` from which
112fec6c5acSUday Bondhugula         // the attributes and regions are used.
113fec6c5acSUday Bondhugula         invokeCreateWithInferredReturnType<OpWithInferTypeInterfaceOp>(op);
114fec6c5acSUday Bondhugula         invokeCreateWithInferredReturnType<
115fec6c5acSUday Bondhugula             OpWithShapedTypeInferTypeInterfaceOp>(op);
116fec6c5acSUday Bondhugula       };
117fec6c5acSUday Bondhugula       return;
118fec6c5acSUday Bondhugula     }
119fec6c5acSUday Bondhugula     if (getFunction().getName() == "testReifyFunctions") {
120fec6c5acSUday Bondhugula       std::vector<Operation *> ops;
121fec6c5acSUday Bondhugula       // Collect ops to avoid triggering on inserted ops.
122fec6c5acSUday Bondhugula       for (auto &op : getFunction().getBody().front())
123fec6c5acSUday Bondhugula         if (isa<OpWithShapedTypeInferTypeInterfaceOp>(op))
124fec6c5acSUday Bondhugula           ops.push_back(&op);
125fec6c5acSUday Bondhugula       // Generate test patterns for each, but skip terminator.
126fec6c5acSUday Bondhugula       for (auto *op : ops)
127fec6c5acSUday Bondhugula         reifyReturnShape(op);
128fec6c5acSUday Bondhugula     }
129fec6c5acSUday Bondhugula   }
130fec6c5acSUday Bondhugula };
131fec6c5acSUday Bondhugula } // end anonymous namespace
132fec6c5acSUday Bondhugula 
1339ba37b3bSJacques Pienaar namespace {
1349ba37b3bSJacques Pienaar struct TestDerivedAttributeDriver
1359ba37b3bSJacques Pienaar     : public PassWrapper<TestDerivedAttributeDriver, FunctionPass> {
1369ba37b3bSJacques Pienaar   void runOnFunction() override;
1379ba37b3bSJacques Pienaar };
1389ba37b3bSJacques Pienaar } // end anonymous namespace
1399ba37b3bSJacques Pienaar 
1409ba37b3bSJacques Pienaar void TestDerivedAttributeDriver::runOnFunction() {
1419ba37b3bSJacques Pienaar   getFunction().walk([](DerivedAttributeOpInterface dOp) {
1429ba37b3bSJacques Pienaar     auto dAttr = dOp.materializeDerivedAttributes();
1439ba37b3bSJacques Pienaar     if (!dAttr)
1449ba37b3bSJacques Pienaar       return;
1459ba37b3bSJacques Pienaar     for (auto d : dAttr)
1469ba37b3bSJacques Pienaar       dOp.emitRemark() << d.first << " = " << d.second;
1479ba37b3bSJacques Pienaar   });
1489ba37b3bSJacques Pienaar }
1499ba37b3bSJacques Pienaar 
150fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
151fec6c5acSUday Bondhugula // Legalization Driver.
152fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
153fec6c5acSUday Bondhugula 
154fec6c5acSUday Bondhugula namespace {
155fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
156fec6c5acSUday Bondhugula // Region-Block Rewrite Testing
157fec6c5acSUday Bondhugula 
158fec6c5acSUday Bondhugula /// This pattern is a simple pattern that inlines the first region of a given
159fec6c5acSUday Bondhugula /// operation into the parent region.
160fec6c5acSUday Bondhugula struct TestRegionRewriteBlockMovement : public ConversionPattern {
161fec6c5acSUday Bondhugula   TestRegionRewriteBlockMovement(MLIRContext *ctx)
162fec6c5acSUday Bondhugula       : ConversionPattern("test.region", 1, ctx) {}
163fec6c5acSUday Bondhugula 
164fec6c5acSUday Bondhugula   LogicalResult
165fec6c5acSUday Bondhugula   matchAndRewrite(Operation *op, ArrayRef<Value> operands,
166fec6c5acSUday Bondhugula                   ConversionPatternRewriter &rewriter) const final {
167fec6c5acSUday Bondhugula     // Inline this region into the parent region.
168fec6c5acSUday Bondhugula     auto &parentRegion = *op->getParentRegion();
169fec6c5acSUday Bondhugula     if (op->getAttr("legalizer.should_clone"))
170fec6c5acSUday Bondhugula       rewriter.cloneRegionBefore(op->getRegion(0), parentRegion,
171fec6c5acSUday Bondhugula                                  parentRegion.end());
172fec6c5acSUday Bondhugula     else
173fec6c5acSUday Bondhugula       rewriter.inlineRegionBefore(op->getRegion(0), parentRegion,
174fec6c5acSUday Bondhugula                                   parentRegion.end());
175fec6c5acSUday Bondhugula 
176fec6c5acSUday Bondhugula     // Drop this operation.
177fec6c5acSUday Bondhugula     rewriter.eraseOp(op);
178fec6c5acSUday Bondhugula     return success();
179fec6c5acSUday Bondhugula   }
180fec6c5acSUday Bondhugula };
181fec6c5acSUday Bondhugula /// This pattern is a simple pattern that generates a region containing an
182fec6c5acSUday Bondhugula /// illegal operation.
183fec6c5acSUday Bondhugula struct TestRegionRewriteUndo : public RewritePattern {
184fec6c5acSUday Bondhugula   TestRegionRewriteUndo(MLIRContext *ctx)
185fec6c5acSUday Bondhugula       : RewritePattern("test.region_builder", 1, ctx) {}
186fec6c5acSUday Bondhugula 
187fec6c5acSUday Bondhugula   LogicalResult matchAndRewrite(Operation *op,
188fec6c5acSUday Bondhugula                                 PatternRewriter &rewriter) const final {
189fec6c5acSUday Bondhugula     // Create the region operation with an entry block containing arguments.
190fec6c5acSUday Bondhugula     OperationState newRegion(op->getLoc(), "test.region");
191fec6c5acSUday Bondhugula     newRegion.addRegion();
192fec6c5acSUday Bondhugula     auto *regionOp = rewriter.createOperation(newRegion);
193fec6c5acSUday Bondhugula     auto *entryBlock = rewriter.createBlock(&regionOp->getRegion(0));
194fec6c5acSUday Bondhugula     entryBlock->addArgument(rewriter.getIntegerType(64));
195fec6c5acSUday Bondhugula 
196fec6c5acSUday Bondhugula     // Add an explicitly illegal operation to ensure the conversion fails.
197fec6c5acSUday Bondhugula     rewriter.create<ILLegalOpF>(op->getLoc(), rewriter.getIntegerType(32));
198fec6c5acSUday Bondhugula     rewriter.create<TestValidOp>(op->getLoc(), ArrayRef<Value>());
199fec6c5acSUday Bondhugula 
200fec6c5acSUday Bondhugula     // Drop this operation.
201fec6c5acSUday Bondhugula     rewriter.eraseOp(op);
202fec6c5acSUday Bondhugula     return success();
203fec6c5acSUday Bondhugula   }
204fec6c5acSUday Bondhugula };
205f27f1e8cSAlex Zinenko /// A simple pattern that creates a block at the end of the parent region of the
206f27f1e8cSAlex Zinenko /// matched operation.
207f27f1e8cSAlex Zinenko struct TestCreateBlock : public RewritePattern {
208f27f1e8cSAlex Zinenko   TestCreateBlock(MLIRContext *ctx)
209f27f1e8cSAlex Zinenko       : RewritePattern("test.create_block", /*benefit=*/1, ctx) {}
210f27f1e8cSAlex Zinenko 
211f27f1e8cSAlex Zinenko   LogicalResult matchAndRewrite(Operation *op,
212f27f1e8cSAlex Zinenko                                 PatternRewriter &rewriter) const final {
213f27f1e8cSAlex Zinenko     Region &region = *op->getParentRegion();
214f27f1e8cSAlex Zinenko     Type i32Type = rewriter.getIntegerType(32);
215f27f1e8cSAlex Zinenko     rewriter.createBlock(&region, region.end(), {i32Type, i32Type});
216f27f1e8cSAlex Zinenko     rewriter.create<TerminatorOp>(op->getLoc());
217f27f1e8cSAlex Zinenko     rewriter.replaceOp(op, {});
218f27f1e8cSAlex Zinenko     return success();
219f27f1e8cSAlex Zinenko   }
220f27f1e8cSAlex Zinenko };
221f27f1e8cSAlex Zinenko 
222f27f1e8cSAlex Zinenko /// A simple pattern that creates a block containing an invalid operaiton in
223f27f1e8cSAlex Zinenko /// order to trigger the block creation undo mechanism.
224f27f1e8cSAlex Zinenko struct TestCreateIllegalBlock : public RewritePattern {
225f27f1e8cSAlex Zinenko   TestCreateIllegalBlock(MLIRContext *ctx)
226f27f1e8cSAlex Zinenko       : RewritePattern("test.create_illegal_block", /*benefit=*/1, ctx) {}
227f27f1e8cSAlex Zinenko 
228f27f1e8cSAlex Zinenko   LogicalResult matchAndRewrite(Operation *op,
229f27f1e8cSAlex Zinenko                                 PatternRewriter &rewriter) const final {
230f27f1e8cSAlex Zinenko     Region &region = *op->getParentRegion();
231f27f1e8cSAlex Zinenko     Type i32Type = rewriter.getIntegerType(32);
232f27f1e8cSAlex Zinenko     rewriter.createBlock(&region, region.end(), {i32Type, i32Type});
233f27f1e8cSAlex Zinenko     // Create an illegal op to ensure the conversion fails.
234f27f1e8cSAlex Zinenko     rewriter.create<ILLegalOpF>(op->getLoc(), i32Type);
235f27f1e8cSAlex Zinenko     rewriter.create<TerminatorOp>(op->getLoc());
236f27f1e8cSAlex Zinenko     rewriter.replaceOp(op, {});
237f27f1e8cSAlex Zinenko     return success();
238f27f1e8cSAlex Zinenko   }
239f27f1e8cSAlex Zinenko };
240fec6c5acSUday Bondhugula 
2410816de16SRiver Riddle /// A simple pattern that tests the undo mechanism when replacing the uses of a
2420816de16SRiver Riddle /// block argument.
2430816de16SRiver Riddle struct TestUndoBlockArgReplace : public ConversionPattern {
2440816de16SRiver Riddle   TestUndoBlockArgReplace(MLIRContext *ctx)
2450816de16SRiver Riddle       : ConversionPattern("test.undo_block_arg_replace", /*benefit=*/1, ctx) {}
2460816de16SRiver Riddle 
2470816de16SRiver Riddle   LogicalResult
2480816de16SRiver Riddle   matchAndRewrite(Operation *op, ArrayRef<Value> operands,
2490816de16SRiver Riddle                   ConversionPatternRewriter &rewriter) const final {
2500816de16SRiver Riddle     auto illegalOp =
2510816de16SRiver Riddle         rewriter.create<ILLegalOpF>(op->getLoc(), rewriter.getF32Type());
2520816de16SRiver Riddle     rewriter.replaceUsesOfBlockArgument(op->getRegion(0).front().getArgument(0),
2530816de16SRiver Riddle                                         illegalOp);
2540816de16SRiver Riddle     rewriter.updateRootInPlace(op, [] {});
2550816de16SRiver Riddle     return success();
2560816de16SRiver Riddle   }
2570816de16SRiver Riddle };
2580816de16SRiver Riddle 
259fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
260fec6c5acSUday Bondhugula // Type-Conversion Rewrite Testing
261fec6c5acSUday Bondhugula 
262fec6c5acSUday Bondhugula /// This patterns erases a region operation that has had a type conversion.
263fec6c5acSUday Bondhugula struct TestDropOpSignatureConversion : public ConversionPattern {
264fec6c5acSUday Bondhugula   TestDropOpSignatureConversion(MLIRContext *ctx, TypeConverter &converter)
265fec6c5acSUday Bondhugula       : ConversionPattern("test.drop_region_op", 1, ctx), converter(converter) {
266fec6c5acSUday Bondhugula   }
267fec6c5acSUday Bondhugula   LogicalResult
268fec6c5acSUday Bondhugula   matchAndRewrite(Operation *op, ArrayRef<Value> operands,
269fec6c5acSUday Bondhugula                   ConversionPatternRewriter &rewriter) const override {
270fec6c5acSUday Bondhugula     Region &region = op->getRegion(0);
271fec6c5acSUday Bondhugula     Block *entry = &region.front();
272fec6c5acSUday Bondhugula 
273fec6c5acSUday Bondhugula     // Convert the original entry arguments.
274fec6c5acSUday Bondhugula     TypeConverter::SignatureConversion result(entry->getNumArguments());
275fec6c5acSUday Bondhugula     for (unsigned i = 0, e = entry->getNumArguments(); i != e; ++i)
276fec6c5acSUday Bondhugula       if (failed(converter.convertSignatureArg(
277fec6c5acSUday Bondhugula               i, entry->getArgument(i).getType(), result)))
278fec6c5acSUday Bondhugula         return failure();
279fec6c5acSUday Bondhugula 
280fec6c5acSUday Bondhugula     // Convert the region signature and just drop the operation.
281fec6c5acSUday Bondhugula     rewriter.applySignatureConversion(&region, result);
282fec6c5acSUday Bondhugula     rewriter.eraseOp(op);
283fec6c5acSUday Bondhugula     return success();
284fec6c5acSUday Bondhugula   }
285fec6c5acSUday Bondhugula 
286fec6c5acSUday Bondhugula   /// The type converter to use when rewriting the signature.
287fec6c5acSUday Bondhugula   TypeConverter &converter;
288fec6c5acSUday Bondhugula };
289fec6c5acSUday Bondhugula /// This pattern simply updates the operands of the given operation.
290fec6c5acSUday Bondhugula struct TestPassthroughInvalidOp : public ConversionPattern {
291fec6c5acSUday Bondhugula   TestPassthroughInvalidOp(MLIRContext *ctx)
292fec6c5acSUday Bondhugula       : ConversionPattern("test.invalid", 1, ctx) {}
293fec6c5acSUday Bondhugula   LogicalResult
294fec6c5acSUday Bondhugula   matchAndRewrite(Operation *op, ArrayRef<Value> operands,
295fec6c5acSUday Bondhugula                   ConversionPatternRewriter &rewriter) const final {
296fec6c5acSUday Bondhugula     rewriter.replaceOpWithNewOp<TestValidOp>(op, llvm::None, operands,
297fec6c5acSUday Bondhugula                                              llvm::None);
298fec6c5acSUday Bondhugula     return success();
299fec6c5acSUday Bondhugula   }
300fec6c5acSUday Bondhugula };
301fec6c5acSUday Bondhugula /// This pattern handles the case of a split return value.
302fec6c5acSUday Bondhugula struct TestSplitReturnType : public ConversionPattern {
303fec6c5acSUday Bondhugula   TestSplitReturnType(MLIRContext *ctx)
304fec6c5acSUday Bondhugula       : ConversionPattern("test.return", 1, ctx) {}
305fec6c5acSUday Bondhugula   LogicalResult
306fec6c5acSUday Bondhugula   matchAndRewrite(Operation *op, ArrayRef<Value> operands,
307fec6c5acSUday Bondhugula                   ConversionPatternRewriter &rewriter) const final {
308fec6c5acSUday Bondhugula     // Check for a return of F32.
309fec6c5acSUday Bondhugula     if (op->getNumOperands() != 1 || !op->getOperand(0).getType().isF32())
310fec6c5acSUday Bondhugula       return failure();
311fec6c5acSUday Bondhugula 
312fec6c5acSUday Bondhugula     // Check if the first operation is a cast operation, if it is we use the
313fec6c5acSUday Bondhugula     // results directly.
314fec6c5acSUday Bondhugula     auto *defOp = operands[0].getDefiningOp();
315fec6c5acSUday Bondhugula     if (auto packerOp = llvm::dyn_cast_or_null<TestCastOp>(defOp)) {
316fec6c5acSUday Bondhugula       rewriter.replaceOpWithNewOp<TestReturnOp>(op, packerOp.getOperands());
317fec6c5acSUday Bondhugula       return success();
318fec6c5acSUday Bondhugula     }
319fec6c5acSUday Bondhugula 
320fec6c5acSUday Bondhugula     // Otherwise, fail to match.
321fec6c5acSUday Bondhugula     return failure();
322fec6c5acSUday Bondhugula   }
323fec6c5acSUday Bondhugula };
324fec6c5acSUday Bondhugula 
325fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
326fec6c5acSUday Bondhugula // Multi-Level Type-Conversion Rewrite Testing
327fec6c5acSUday Bondhugula struct TestChangeProducerTypeI32ToF32 : public ConversionPattern {
328fec6c5acSUday Bondhugula   TestChangeProducerTypeI32ToF32(MLIRContext *ctx)
329fec6c5acSUday Bondhugula       : ConversionPattern("test.type_producer", 1, ctx) {}
330fec6c5acSUday Bondhugula   LogicalResult
331fec6c5acSUday Bondhugula   matchAndRewrite(Operation *op, ArrayRef<Value> operands,
332fec6c5acSUday Bondhugula                   ConversionPatternRewriter &rewriter) const final {
333fec6c5acSUday Bondhugula     // If the type is I32, change the type to F32.
334fec6c5acSUday Bondhugula     if (!Type(*op->result_type_begin()).isSignlessInteger(32))
335fec6c5acSUday Bondhugula       return failure();
336fec6c5acSUday Bondhugula     rewriter.replaceOpWithNewOp<TestTypeProducerOp>(op, rewriter.getF32Type());
337fec6c5acSUday Bondhugula     return success();
338fec6c5acSUday Bondhugula   }
339fec6c5acSUday Bondhugula };
340fec6c5acSUday Bondhugula struct TestChangeProducerTypeF32ToF64 : public ConversionPattern {
341fec6c5acSUday Bondhugula   TestChangeProducerTypeF32ToF64(MLIRContext *ctx)
342fec6c5acSUday Bondhugula       : ConversionPattern("test.type_producer", 1, ctx) {}
343fec6c5acSUday Bondhugula   LogicalResult
344fec6c5acSUday Bondhugula   matchAndRewrite(Operation *op, ArrayRef<Value> operands,
345fec6c5acSUday Bondhugula                   ConversionPatternRewriter &rewriter) const final {
346fec6c5acSUday Bondhugula     // If the type is F32, change the type to F64.
347fec6c5acSUday Bondhugula     if (!Type(*op->result_type_begin()).isF32())
348fec6c5acSUday Bondhugula       return rewriter.notifyMatchFailure(op, "expected single f32 operand");
349fec6c5acSUday Bondhugula     rewriter.replaceOpWithNewOp<TestTypeProducerOp>(op, rewriter.getF64Type());
350fec6c5acSUday Bondhugula     return success();
351fec6c5acSUday Bondhugula   }
352fec6c5acSUday Bondhugula };
353fec6c5acSUday Bondhugula struct TestChangeProducerTypeF32ToInvalid : public ConversionPattern {
354fec6c5acSUday Bondhugula   TestChangeProducerTypeF32ToInvalid(MLIRContext *ctx)
355fec6c5acSUday Bondhugula       : ConversionPattern("test.type_producer", 10, ctx) {}
356fec6c5acSUday Bondhugula   LogicalResult
357fec6c5acSUday Bondhugula   matchAndRewrite(Operation *op, ArrayRef<Value> operands,
358fec6c5acSUday Bondhugula                   ConversionPatternRewriter &rewriter) const final {
359fec6c5acSUday Bondhugula     // Always convert to B16, even though it is not a legal type. This tests
360fec6c5acSUday Bondhugula     // that values are unmapped correctly.
361fec6c5acSUday Bondhugula     rewriter.replaceOpWithNewOp<TestTypeProducerOp>(op, rewriter.getBF16Type());
362fec6c5acSUday Bondhugula     return success();
363fec6c5acSUday Bondhugula   }
364fec6c5acSUday Bondhugula };
365fec6c5acSUday Bondhugula struct TestUpdateConsumerType : public ConversionPattern {
366fec6c5acSUday Bondhugula   TestUpdateConsumerType(MLIRContext *ctx)
367fec6c5acSUday Bondhugula       : ConversionPattern("test.type_consumer", 1, ctx) {}
368fec6c5acSUday Bondhugula   LogicalResult
369fec6c5acSUday Bondhugula   matchAndRewrite(Operation *op, ArrayRef<Value> operands,
370fec6c5acSUday Bondhugula                   ConversionPatternRewriter &rewriter) const final {
371fec6c5acSUday Bondhugula     // Verify that the incoming operand has been successfully remapped to F64.
372fec6c5acSUday Bondhugula     if (!operands[0].getType().isF64())
373fec6c5acSUday Bondhugula       return failure();
374fec6c5acSUday Bondhugula     rewriter.replaceOpWithNewOp<TestTypeConsumerOp>(op, operands[0]);
375fec6c5acSUday Bondhugula     return success();
376fec6c5acSUday Bondhugula   }
377fec6c5acSUday Bondhugula };
378fec6c5acSUday Bondhugula 
379fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
380fec6c5acSUday Bondhugula // Non-Root Replacement Rewrite Testing
381fec6c5acSUday Bondhugula /// This pattern generates an invalid operation, but replaces it before the
382fec6c5acSUday Bondhugula /// pattern is finished. This checks that we don't need to legalize the
383fec6c5acSUday Bondhugula /// temporary op.
384fec6c5acSUday Bondhugula struct TestNonRootReplacement : public RewritePattern {
385fec6c5acSUday Bondhugula   TestNonRootReplacement(MLIRContext *ctx)
386fec6c5acSUday Bondhugula       : RewritePattern("test.replace_non_root", 1, ctx) {}
387fec6c5acSUday Bondhugula 
388fec6c5acSUday Bondhugula   LogicalResult matchAndRewrite(Operation *op,
389fec6c5acSUday Bondhugula                                 PatternRewriter &rewriter) const final {
390fec6c5acSUday Bondhugula     auto resultType = *op->result_type_begin();
391fec6c5acSUday Bondhugula     auto illegalOp = rewriter.create<ILLegalOpF>(op->getLoc(), resultType);
392fec6c5acSUday Bondhugula     auto legalOp = rewriter.create<LegalOpB>(op->getLoc(), resultType);
393fec6c5acSUday Bondhugula 
394fec6c5acSUday Bondhugula     rewriter.replaceOp(illegalOp, {legalOp});
395fec6c5acSUday Bondhugula     rewriter.replaceOp(op, {illegalOp});
396fec6c5acSUday Bondhugula     return success();
397fec6c5acSUday Bondhugula   }
398fec6c5acSUday Bondhugula };
399bd1ccfe6SRiver Riddle 
400bd1ccfe6SRiver Riddle //===----------------------------------------------------------------------===//
401bd1ccfe6SRiver Riddle // Recursive Rewrite Testing
402bd1ccfe6SRiver Riddle /// This pattern is applied to the same operation multiple times, but has a
403bd1ccfe6SRiver Riddle /// bounded recursion.
404bd1ccfe6SRiver Riddle struct TestBoundedRecursiveRewrite
405bd1ccfe6SRiver Riddle     : public OpRewritePattern<TestRecursiveRewriteOp> {
406bd1ccfe6SRiver Riddle   using OpRewritePattern<TestRecursiveRewriteOp>::OpRewritePattern;
407bd1ccfe6SRiver Riddle 
408bd1ccfe6SRiver Riddle   LogicalResult matchAndRewrite(TestRecursiveRewriteOp op,
409bd1ccfe6SRiver Riddle                                 PatternRewriter &rewriter) const final {
410bd1ccfe6SRiver Riddle     // Decrement the depth of the op in-place.
411bd1ccfe6SRiver Riddle     rewriter.updateRootInPlace(op, [&] {
412bd1ccfe6SRiver Riddle       op.setAttr("depth",
413bd1ccfe6SRiver Riddle                  rewriter.getI64IntegerAttr(op.depth().getSExtValue() - 1));
414bd1ccfe6SRiver Riddle     });
415bd1ccfe6SRiver Riddle     return success();
416bd1ccfe6SRiver Riddle   }
417bd1ccfe6SRiver Riddle 
418bd1ccfe6SRiver Riddle   /// The conversion target handles bounding the recursion of this pattern.
419bd1ccfe6SRiver Riddle   bool hasBoundedRewriteRecursion() const final { return true; }
420bd1ccfe6SRiver Riddle };
421fec6c5acSUday Bondhugula } // namespace
422fec6c5acSUday Bondhugula 
423fec6c5acSUday Bondhugula namespace {
424fec6c5acSUday Bondhugula struct TestTypeConverter : public TypeConverter {
425fec6c5acSUday Bondhugula   using TypeConverter::TypeConverter;
426fec6c5acSUday Bondhugula   TestTypeConverter() { addConversion(convertType); }
427fec6c5acSUday Bondhugula 
428fec6c5acSUday Bondhugula   static LogicalResult convertType(Type t, SmallVectorImpl<Type> &results) {
429fec6c5acSUday Bondhugula     // Drop I16 types.
430fec6c5acSUday Bondhugula     if (t.isSignlessInteger(16))
431fec6c5acSUday Bondhugula       return success();
432fec6c5acSUday Bondhugula 
433fec6c5acSUday Bondhugula     // Convert I64 to F64.
434fec6c5acSUday Bondhugula     if (t.isSignlessInteger(64)) {
435fec6c5acSUday Bondhugula       results.push_back(FloatType::getF64(t.getContext()));
436fec6c5acSUday Bondhugula       return success();
437fec6c5acSUday Bondhugula     }
438fec6c5acSUday Bondhugula 
439fec6c5acSUday Bondhugula     // Split F32 into F16,F16.
440fec6c5acSUday Bondhugula     if (t.isF32()) {
441fec6c5acSUday Bondhugula       results.assign(2, FloatType::getF16(t.getContext()));
442fec6c5acSUday Bondhugula       return success();
443fec6c5acSUday Bondhugula     }
444fec6c5acSUday Bondhugula 
445fec6c5acSUday Bondhugula     // Otherwise, convert the type directly.
446fec6c5acSUday Bondhugula     results.push_back(t);
447fec6c5acSUday Bondhugula     return success();
448fec6c5acSUday Bondhugula   }
449fec6c5acSUday Bondhugula 
450fec6c5acSUday Bondhugula   /// Override the hook to materialize a conversion. This is necessary because
451fec6c5acSUday Bondhugula   /// we generate 1->N type mappings.
452fec6c5acSUday Bondhugula   Operation *materializeConversion(PatternRewriter &rewriter, Type resultType,
453fec6c5acSUday Bondhugula                                    ArrayRef<Value> inputs,
454fec6c5acSUday Bondhugula                                    Location loc) override {
455fec6c5acSUday Bondhugula     return rewriter.create<TestCastOp>(loc, resultType, inputs);
456fec6c5acSUday Bondhugula   }
457fec6c5acSUday Bondhugula };
458fec6c5acSUday Bondhugula 
459fec6c5acSUday Bondhugula struct TestLegalizePatternDriver
46080aca1eaSRiver Riddle     : public PassWrapper<TestLegalizePatternDriver, OperationPass<ModuleOp>> {
461fec6c5acSUday Bondhugula   /// The mode of conversion to use with the driver.
462fec6c5acSUday Bondhugula   enum class ConversionMode { Analysis, Full, Partial };
463fec6c5acSUday Bondhugula 
464fec6c5acSUday Bondhugula   TestLegalizePatternDriver(ConversionMode mode) : mode(mode) {}
465fec6c5acSUday Bondhugula 
466722f909fSRiver Riddle   void runOnOperation() override {
467fec6c5acSUday Bondhugula     TestTypeConverter converter;
468fec6c5acSUday Bondhugula     mlir::OwningRewritePatternList patterns;
469fec6c5acSUday Bondhugula     populateWithGenerated(&getContext(), &patterns);
4700816de16SRiver Riddle     patterns.insert<TestRegionRewriteBlockMovement, TestRegionRewriteUndo,
4710816de16SRiver Riddle                     TestCreateBlock, TestCreateIllegalBlock,
4720816de16SRiver Riddle                     TestUndoBlockArgReplace, TestPassthroughInvalidOp,
4730816de16SRiver Riddle                     TestSplitReturnType, TestChangeProducerTypeI32ToF32,
4740816de16SRiver Riddle                     TestChangeProducerTypeF32ToF64,
475fec6c5acSUday Bondhugula                     TestChangeProducerTypeF32ToInvalid, TestUpdateConsumerType,
4760816de16SRiver Riddle                     TestNonRootReplacement, TestBoundedRecursiveRewrite>(
4770816de16SRiver Riddle         &getContext());
478fec6c5acSUday Bondhugula     patterns.insert<TestDropOpSignatureConversion>(&getContext(), converter);
479fec6c5acSUday Bondhugula     mlir::populateFuncOpTypeConversionPattern(patterns, &getContext(),
480fec6c5acSUday Bondhugula                                               converter);
481fec6c5acSUday Bondhugula     mlir::populateCallOpTypeConversionPattern(patterns, &getContext(),
482fec6c5acSUday Bondhugula                                               converter);
483fec6c5acSUday Bondhugula 
484fec6c5acSUday Bondhugula     // Define the conversion target used for the test.
485fec6c5acSUday Bondhugula     ConversionTarget target(getContext());
486fec6c5acSUday Bondhugula     target.addLegalOp<ModuleOp, ModuleTerminatorOp>();
487f27f1e8cSAlex Zinenko     target.addLegalOp<LegalOpA, LegalOpB, TestCastOp, TestValidOp,
488f27f1e8cSAlex Zinenko                       TerminatorOp>();
489fec6c5acSUday Bondhugula     target
490fec6c5acSUday Bondhugula         .addIllegalOp<ILLegalOpF, TestRegionBuilderOp, TestOpWithRegionFold>();
491fec6c5acSUday Bondhugula     target.addDynamicallyLegalOp<TestReturnOp>([](TestReturnOp op) {
492fec6c5acSUday Bondhugula       // Don't allow F32 operands.
493fec6c5acSUday Bondhugula       return llvm::none_of(op.getOperandTypes(),
494fec6c5acSUday Bondhugula                            [](Type type) { return type.isF32(); });
495fec6c5acSUday Bondhugula     });
496fec6c5acSUday Bondhugula     target.addDynamicallyLegalOp<FuncOp>(
497fec6c5acSUday Bondhugula         [&](FuncOp op) { return converter.isSignatureLegal(op.getType()); });
498fec6c5acSUday Bondhugula 
499fec6c5acSUday Bondhugula     // Expect the type_producer/type_consumer operations to only operate on f64.
500fec6c5acSUday Bondhugula     target.addDynamicallyLegalOp<TestTypeProducerOp>(
501fec6c5acSUday Bondhugula         [](TestTypeProducerOp op) { return op.getType().isF64(); });
502fec6c5acSUday Bondhugula     target.addDynamicallyLegalOp<TestTypeConsumerOp>([](TestTypeConsumerOp op) {
503fec6c5acSUday Bondhugula       return op.getOperand().getType().isF64();
504fec6c5acSUday Bondhugula     });
505fec6c5acSUday Bondhugula 
506fec6c5acSUday Bondhugula     // Check support for marking certain operations as recursively legal.
507fec6c5acSUday Bondhugula     target.markOpRecursivelyLegal<FuncOp, ModuleOp>([](Operation *op) {
508fec6c5acSUday Bondhugula       return static_cast<bool>(
509fec6c5acSUday Bondhugula           op->getAttrOfType<UnitAttr>("test.recursively_legal"));
510fec6c5acSUday Bondhugula     });
511fec6c5acSUday Bondhugula 
512bd1ccfe6SRiver Riddle     // Mark the bound recursion operation as dynamically legal.
513bd1ccfe6SRiver Riddle     target.addDynamicallyLegalOp<TestRecursiveRewriteOp>(
514bd1ccfe6SRiver Riddle         [](TestRecursiveRewriteOp op) { return op.depth() == 0; });
515bd1ccfe6SRiver Riddle 
516fec6c5acSUday Bondhugula     // Handle a partial conversion.
517fec6c5acSUday Bondhugula     if (mode == ConversionMode::Partial) {
518722f909fSRiver Riddle       (void)applyPartialConversion(getOperation(), target, patterns,
519722f909fSRiver Riddle                                    &converter);
520fec6c5acSUday Bondhugula       return;
521fec6c5acSUday Bondhugula     }
522fec6c5acSUday Bondhugula 
523fec6c5acSUday Bondhugula     // Handle a full conversion.
524fec6c5acSUday Bondhugula     if (mode == ConversionMode::Full) {
525fec6c5acSUday Bondhugula       // Check support for marking unknown operations as dynamically legal.
526fec6c5acSUday Bondhugula       target.markUnknownOpDynamicallyLegal([](Operation *op) {
527fec6c5acSUday Bondhugula         return (bool)op->getAttrOfType<UnitAttr>("test.dynamically_legal");
528fec6c5acSUday Bondhugula       });
529fec6c5acSUday Bondhugula 
530722f909fSRiver Riddle       (void)applyFullConversion(getOperation(), target, patterns, &converter);
531fec6c5acSUday Bondhugula       return;
532fec6c5acSUday Bondhugula     }
533fec6c5acSUday Bondhugula 
534fec6c5acSUday Bondhugula     // Otherwise, handle an analysis conversion.
535fec6c5acSUday Bondhugula     assert(mode == ConversionMode::Analysis);
536fec6c5acSUday Bondhugula 
537fec6c5acSUday Bondhugula     // Analyze the convertible operations.
538fec6c5acSUday Bondhugula     DenseSet<Operation *> legalizedOps;
539722f909fSRiver Riddle     if (failed(applyAnalysisConversion(getOperation(), target, patterns,
540fec6c5acSUday Bondhugula                                        legalizedOps, &converter)))
541fec6c5acSUday Bondhugula       return signalPassFailure();
542fec6c5acSUday Bondhugula 
543fec6c5acSUday Bondhugula     // Emit remarks for each legalizable operation.
544fec6c5acSUday Bondhugula     for (auto *op : legalizedOps)
545fec6c5acSUday Bondhugula       op->emitRemark() << "op '" << op->getName() << "' is legalizable";
546fec6c5acSUday Bondhugula   }
547fec6c5acSUday Bondhugula 
548fec6c5acSUday Bondhugula   /// The mode of conversion to use.
549fec6c5acSUday Bondhugula   ConversionMode mode;
550fec6c5acSUday Bondhugula };
551fec6c5acSUday Bondhugula } // end anonymous namespace
552fec6c5acSUday Bondhugula 
553fec6c5acSUday Bondhugula static llvm::cl::opt<TestLegalizePatternDriver::ConversionMode>
554fec6c5acSUday Bondhugula     legalizerConversionMode(
555fec6c5acSUday Bondhugula         "test-legalize-mode",
556fec6c5acSUday Bondhugula         llvm::cl::desc("The legalization mode to use with the test driver"),
557fec6c5acSUday Bondhugula         llvm::cl::init(TestLegalizePatternDriver::ConversionMode::Partial),
558fec6c5acSUday Bondhugula         llvm::cl::values(
559fec6c5acSUday Bondhugula             clEnumValN(TestLegalizePatternDriver::ConversionMode::Analysis,
560fec6c5acSUday Bondhugula                        "analysis", "Perform an analysis conversion"),
561fec6c5acSUday Bondhugula             clEnumValN(TestLegalizePatternDriver::ConversionMode::Full, "full",
562fec6c5acSUday Bondhugula                        "Perform a full conversion"),
563fec6c5acSUday Bondhugula             clEnumValN(TestLegalizePatternDriver::ConversionMode::Partial,
564fec6c5acSUday Bondhugula                        "partial", "Perform a partial conversion")));
565fec6c5acSUday Bondhugula 
566fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
567fec6c5acSUday Bondhugula // ConversionPatternRewriter::getRemappedValue testing. This method is used
5685aacce3dSKazuaki Ishizaki // to get the remapped value of an original value that was replaced using
569fec6c5acSUday Bondhugula // ConversionPatternRewriter.
570fec6c5acSUday Bondhugula namespace {
571fec6c5acSUday Bondhugula /// Converter that replaces a one-result one-operand OneVResOneVOperandOp1 with
572fec6c5acSUday Bondhugula /// a one-operand two-result OneVResOneVOperandOp1 by replicating its original
573fec6c5acSUday Bondhugula /// operand twice.
574fec6c5acSUday Bondhugula ///
575fec6c5acSUday Bondhugula /// Example:
576fec6c5acSUday Bondhugula ///   %1 = test.one_variadic_out_one_variadic_in1"(%0)
577fec6c5acSUday Bondhugula /// is replaced with:
578fec6c5acSUday Bondhugula ///   %1 = test.one_variadic_out_one_variadic_in1"(%0, %0)
579fec6c5acSUday Bondhugula struct OneVResOneVOperandOp1Converter
580fec6c5acSUday Bondhugula     : public OpConversionPattern<OneVResOneVOperandOp1> {
581fec6c5acSUday Bondhugula   using OpConversionPattern<OneVResOneVOperandOp1>::OpConversionPattern;
582fec6c5acSUday Bondhugula 
583fec6c5acSUday Bondhugula   LogicalResult
584fec6c5acSUday Bondhugula   matchAndRewrite(OneVResOneVOperandOp1 op, ArrayRef<Value> operands,
585fec6c5acSUday Bondhugula                   ConversionPatternRewriter &rewriter) const override {
586fec6c5acSUday Bondhugula     auto origOps = op.getOperands();
587fec6c5acSUday Bondhugula     assert(std::distance(origOps.begin(), origOps.end()) == 1 &&
588fec6c5acSUday Bondhugula            "One operand expected");
589fec6c5acSUday Bondhugula     Value origOp = *origOps.begin();
590fec6c5acSUday Bondhugula     SmallVector<Value, 2> remappedOperands;
591fec6c5acSUday Bondhugula     // Replicate the remapped original operand twice. Note that we don't used
592fec6c5acSUday Bondhugula     // the remapped 'operand' since the goal is testing 'getRemappedValue'.
593fec6c5acSUday Bondhugula     remappedOperands.push_back(rewriter.getRemappedValue(origOp));
594fec6c5acSUday Bondhugula     remappedOperands.push_back(rewriter.getRemappedValue(origOp));
595fec6c5acSUday Bondhugula 
596fec6c5acSUday Bondhugula     rewriter.replaceOpWithNewOp<OneVResOneVOperandOp1>(op, op.getResultTypes(),
597fec6c5acSUday Bondhugula                                                        remappedOperands);
598fec6c5acSUday Bondhugula     return success();
599fec6c5acSUday Bondhugula   }
600fec6c5acSUday Bondhugula };
601fec6c5acSUday Bondhugula 
60280aca1eaSRiver Riddle struct TestRemappedValue
60380aca1eaSRiver Riddle     : public mlir::PassWrapper<TestRemappedValue, FunctionPass> {
604fec6c5acSUday Bondhugula   void runOnFunction() override {
605fec6c5acSUday Bondhugula     mlir::OwningRewritePatternList patterns;
606fec6c5acSUday Bondhugula     patterns.insert<OneVResOneVOperandOp1Converter>(&getContext());
607fec6c5acSUday Bondhugula 
608fec6c5acSUday Bondhugula     mlir::ConversionTarget target(getContext());
609fec6c5acSUday Bondhugula     target.addLegalOp<ModuleOp, ModuleTerminatorOp, FuncOp, TestReturnOp>();
610fec6c5acSUday Bondhugula     // We make OneVResOneVOperandOp1 legal only when it has more that one
611fec6c5acSUday Bondhugula     // operand. This will trigger the conversion that will replace one-operand
612fec6c5acSUday Bondhugula     // OneVResOneVOperandOp1 with two-operand OneVResOneVOperandOp1.
613fec6c5acSUday Bondhugula     target.addDynamicallyLegalOp<OneVResOneVOperandOp1>(
614fec6c5acSUday Bondhugula         [](Operation *op) -> bool {
615fec6c5acSUday Bondhugula           return std::distance(op->operand_begin(), op->operand_end()) > 1;
616fec6c5acSUday Bondhugula         });
617fec6c5acSUday Bondhugula 
618fec6c5acSUday Bondhugula     if (failed(mlir::applyFullConversion(getFunction(), target, patterns))) {
619fec6c5acSUday Bondhugula       signalPassFailure();
620fec6c5acSUday Bondhugula     }
621fec6c5acSUday Bondhugula   }
622fec6c5acSUday Bondhugula };
623fec6c5acSUday Bondhugula } // end anonymous namespace
624fec6c5acSUday Bondhugula 
625fec6c5acSUday Bondhugula namespace mlir {
626fec6c5acSUday Bondhugula void registerPatternsTestPass() {
627fec6c5acSUday Bondhugula   mlir::PassRegistration<TestReturnTypeDriver>("test-return-type",
628fec6c5acSUday Bondhugula                                                "Run return type functions");
629fec6c5acSUday Bondhugula 
6309ba37b3bSJacques Pienaar   mlir::PassRegistration<TestDerivedAttributeDriver>(
6319ba37b3bSJacques Pienaar       "test-derived-attr", "Run test derived attributes");
6329ba37b3bSJacques Pienaar 
633fec6c5acSUday Bondhugula   mlir::PassRegistration<TestPatternDriver>("test-patterns",
634fec6c5acSUday Bondhugula                                             "Run test dialect patterns");
635fec6c5acSUday Bondhugula 
636fec6c5acSUday Bondhugula   mlir::PassRegistration<TestLegalizePatternDriver>(
637fec6c5acSUday Bondhugula       "test-legalize-patterns", "Run test dialect legalization patterns", [] {
638fec6c5acSUday Bondhugula         return std::make_unique<TestLegalizePatternDriver>(
639fec6c5acSUday Bondhugula             legalizerConversionMode);
640fec6c5acSUday Bondhugula       });
641fec6c5acSUday Bondhugula 
642fec6c5acSUday Bondhugula   PassRegistration<TestRemappedValue>(
643fec6c5acSUday Bondhugula       "test-remapped-value",
644fec6c5acSUday Bondhugula       "Test public remapped value mechanism in ConversionPatternRewriter");
645fec6c5acSUday Bondhugula }
646fec6c5acSUday Bondhugula } // namespace mlir
647