2019-07-18 11:10:39 +08:00
|
|
|
// RUN: mlir-tblgen -gen-rewriters -I %S/../../include %s | FileCheck %s --dump-input-on-failure
|
2019-03-09 05:56:53 +08:00
|
|
|
|
|
|
|
include "mlir/IR/OpBase.td"
|
|
|
|
|
2019-04-30 00:24:09 +08:00
|
|
|
def Test_Dialect : Dialect {
|
|
|
|
let name = "test";
|
2019-05-21 00:33:10 +08:00
|
|
|
let cppNamespace = "";
|
2019-04-30 00:24:09 +08:00
|
|
|
}
|
|
|
|
class NS_Op<string mnemonic, list<OpTrait> traits> :
|
|
|
|
Op<Test_Dialect, mnemonic, traits>;
|
|
|
|
|
|
|
|
def ThreeResultOp : NS_Op<"three_result_op", []> {
|
2019-03-09 05:56:53 +08:00
|
|
|
let arguments = (ins I32:$input);
|
|
|
|
let results = (outs I32:$r1, I32:$r2, I32:$r3);
|
|
|
|
}
|
|
|
|
|
2019-04-30 00:24:09 +08:00
|
|
|
def TwoResultOp : NS_Op<"two_result_op", []> {
|
2019-04-04 03:29:14 +08:00
|
|
|
let arguments = (ins I32:$input);
|
|
|
|
let results = (outs I32:$r1, I32:$r2);
|
|
|
|
}
|
|
|
|
|
2019-04-30 00:24:09 +08:00
|
|
|
def OneResultOp : NS_Op<"one_result_op", []> {
|
2019-03-09 05:56:53 +08:00
|
|
|
let arguments = (ins I32:$input);
|
|
|
|
let results = (outs I32:$r1);
|
|
|
|
}
|
|
|
|
|
2019-05-11 06:27:34 +08:00
|
|
|
def b : Pattern<(ThreeResultOp $input), [
|
2019-03-09 05:57:09 +08:00
|
|
|
(OneResultOp (OneResultOp:$interm $input)),
|
|
|
|
(OneResultOp $interm),
|
|
|
|
(OneResultOp (OneResultOp $interm))
|
|
|
|
]>;
|
|
|
|
|
2019-05-11 06:27:34 +08:00
|
|
|
// CHECK-LABEL: struct b
|
2019-03-09 05:57:09 +08:00
|
|
|
|
|
|
|
// CHECK: void rewrite(
|
|
|
|
// CHECK: auto interm = rewriter.create<OneResultOp>(
|
|
|
|
// CHECK-NEXT: /*input=*/s.input
|
|
|
|
// CHECK: auto vOneResultOp0 = rewriter.create<OneResultOp>(
|
|
|
|
// CHECK-NEXT: /*input=*/interm
|
|
|
|
// CHECK: auto vOneResultOp1 = rewriter.create<OneResultOp>(
|
|
|
|
// CHECK-NEXT: /*input=*/interm
|
|
|
|
// CHECK: auto vOneResultOp2 = rewriter.create<OneResultOp>(
|
|
|
|
// CHECK-NEXT: /*input=*/interm
|
|
|
|
// CHECK: auto vOneResultOp3 = rewriter.create<OneResultOp>(
|
|
|
|
// CHECK-NEXT: /*input=*/vOneResultOp2
|
2019-07-04 08:17:33 +08:00
|
|
|
// CHECK: rewriter.replaceOp(op, {vOneResultOp0.getOperation()->getResult(0), vOneResultOp1.getOperation()->getResult(0), vOneResultOp3.getOperation()->getResult(0)});
|
2019-03-09 05:57:09 +08:00
|
|
|
|
2019-04-04 03:29:14 +08:00
|
|
|
// Test more result patterns than needed for replacement
|
|
|
|
// ---
|
2019-04-30 00:24:09 +08:00
|
|
|
def AdditionalOp : NS_Op<"additional_one_result_op", []> {
|
2019-04-04 03:29:14 +08:00
|
|
|
let arguments = (ins I32:$input);
|
|
|
|
let results = (outs I32:$r1);
|
|
|
|
}
|
2019-05-11 06:27:34 +08:00
|
|
|
def c : Pattern<(TwoResultOp $input), [
|
2019-04-04 03:29:14 +08:00
|
|
|
// Additional op generated to help build the final result but not
|
|
|
|
// directly used to replace the source op
|
|
|
|
(AdditionalOp:$interm $input),
|
|
|
|
|
|
|
|
(OneResultOp $interm),
|
|
|
|
(OneResultOp $input)
|
|
|
|
]>;
|
|
|
|
|
2019-05-11 06:27:34 +08:00
|
|
|
// CHECK-LABEL: struct c
|
2019-04-04 03:29:14 +08:00
|
|
|
|
|
|
|
// CHECK: auto interm = rewriter.create<AdditionalOp>(
|
|
|
|
// CHECK: auto vOneResultOp0 = rewriter.create<OneResultOp>(
|
|
|
|
// CHECK-NEXT: /*input=*/interm
|
|
|
|
// CHECK: auto vOneResultOp1 = rewriter.create<OneResultOp>(
|
2019-07-04 08:17:33 +08:00
|
|
|
// CHECK: rewriter.replaceOp(op, {vOneResultOp0.getOperation()->getResult(0), vOneResultOp1.getOperation()->getResult(0)});
|
2019-07-18 11:10:39 +08:00
|
|
|
|
|
|
|
|
|
|
|
// Test UnitAttr in rewrite patterns
|
|
|
|
// ---
|
|
|
|
|
|
|
|
def UnitAttrOp : NS_Op<"unit_attr_op", []> {
|
|
|
|
let arguments = (ins AnyAttr:$value);
|
|
|
|
let results = (outs NoneType:$output);
|
|
|
|
}
|
|
|
|
|
|
|
|
def NoneOp : NS_Op<"none_op", []> {
|
|
|
|
let results = (outs NoneType:$output);
|
|
|
|
}
|
|
|
|
|
|
|
|
def d : Pat<(UnitAttrOp UnitAttr:$ignore),
|
|
|
|
(NoneOp)>;
|
|
|
|
|
|
|
|
// CHECK-LABEL: struct d
|
|
|
|
// CHECK: PatternMatchResult match(Operation *op0) const override {
|
|
|
|
// CHECK: if (!((attr.isa<UnitAttr>()))) return matchFailure();
|