xref: /llvm-project/mlir/test/mlir-pdll/CodeGen/MLIR/expr.pdll (revision 930916c7f3622870b40138dafcc5f94740404e8c)
1// RUN: mlir-pdll %s -I %S -I %S/../../../../include -split-input-file -x mlir | FileCheck %s
2
3//===----------------------------------------------------------------------===//
4// AttributeExpr
5//===----------------------------------------------------------------------===//
6
7// CHECK: pdl.pattern @AttrExpr
8// CHECK: %[[ATTR:.*]] = attribute = 10
9// CHECK: operation({{.*}}) {"attr" = %[[ATTR]]}
10Pattern AttrExpr => erase op<> { attr = attr<"10"> };
11
12// -----
13
14//===----------------------------------------------------------------------===//
15// CallExpr
16//===----------------------------------------------------------------------===//
17
18// CHECK: pdl.pattern @TestCallWithArgsAndReturn
19// CHECK: %[[ROOT:.*]] = operation
20// CHECK: rewrite %[[ROOT]]
21// CHECK: %[[REPL_OP:.*]] = operation "test.op"
22// CHECK: %[[RESULTS:.*]] = results of %[[REPL_OP]]
23// CHECK: replace %[[ROOT]] with(%[[RESULTS]] : !pdl.range<value>)
24Rewrite TestRewrite(root: Op) -> ValueRange => root;
25Pattern TestCallWithArgsAndReturn => replace root: Op with TestRewrite(op<test.op>);
26
27// -----
28
29// CHECK: pdl.pattern @TestExternalCall
30// CHECK: %[[ROOT:.*]] = operation
31// CHECK: rewrite %[[ROOT]]
32// CHECK: %[[RESULTS:.*]] = apply_native_rewrite "TestRewrite"(%[[ROOT]] : !pdl.operation) : !pdl.range<value>
33// CHECK: replace %[[ROOT]] with(%[[RESULTS]] : !pdl.range<value>)
34Rewrite TestRewrite(op: Op) -> ValueRange;
35Pattern TestExternalCall => replace root: Op with TestRewrite(root);
36
37// -----
38
39// CHECK: pdl.pattern @TestExternalNegatedCall
40// CHECK: %[[ROOT:.*]] = operation
41// CHECK: apply_native_constraint  "TestConstraint"(%[[ROOT]] : !pdl.operation) {isNegated = true}
42// CHECK: rewrite %[[ROOT]]
43// CHECK: erase %[[ROOT]]
44Constraint TestConstraint(op: Op);
45Pattern TestExternalNegatedCall {
46    let root = op : Op;
47    not TestConstraint(root);
48    erase root;
49}
50
51// -----
52
53//===----------------------------------------------------------------------===//
54// MemberAccessExpr
55//===----------------------------------------------------------------------===//
56
57// Handle implicit "all" operation results access.
58// CHECK: pdl.pattern @OpAllResultMemberAccess
59// CHECK: %[[OP0:.*]] = operation
60// CHECK: %[[OP0_RES:.*]] = result 0 of %[[OP0]]
61// CHECK: %[[OP1:.*]] = operation
62// CHECK: %[[OP1_RES:.*]] = results of %[[OP1]]
63// CHECK: operation(%[[OP0_RES]], %[[OP1_RES]] : !pdl.value, !pdl.range<value>)
64Pattern OpAllResultMemberAccess {
65  let singleVar: Value = op<>;
66  let rangeVar: ValueRange = op<>;
67  erase op<>(singleVar, rangeVar);
68}
69
70// -----
71
72// Handle result indexing on unregistered op.
73// CHECK: pdl.pattern @UnregisteredOpResultIndexing
74// CHECK: %[[BAR_OP:.*]] = operation "my_dialect.unregistered_bar"
75// CHECK: %[[BAR_RES:.*]] = result 0 of %[[BAR_OP]]
76// CHECK: operation "my_dialect.unregistered_foo"(%[[BAR_RES]] : !pdl.value)
77Pattern UnregisteredOpResultIndexing {
78  let bar : Op<my_dialect.unregistered_bar>;
79  let op = op<my_dialect.unregistered_foo>(bar.0);
80  erase op;
81}
82
83// -----
84
85// Handle implicit "named" operation results access.
86
87#include "include/ops.td"
88
89// CHECK: pdl.pattern @OpResultMemberAccess
90// CHECK: %[[OP0:.*]] = operation
91// CHECK: %[[RES:.*]] = results 0 of %[[OP0]] -> !pdl.value
92// CHECK: %[[RES1:.*]] = results 0 of %[[OP0]] -> !pdl.value
93// CHECK: %[[RES2:.*]] = results 1 of %[[OP0]] -> !pdl.range<value>
94// CHECK: %[[RES3:.*]] = results 1 of %[[OP0]] -> !pdl.range<value>
95// CHECK: operation(%[[RES]], %[[RES1]], %[[RES2]], %[[RES3]] : !pdl.value, !pdl.value, !pdl.range<value>, !pdl.range<value>)
96Pattern OpResultMemberAccess {
97  let op: Op<test.with_results>;
98  erase op<>(op.0, op.result, op.1, op.var_result);
99}
100
101// -----
102
103// CHECK: pdl.pattern @TupleMemberAccessNumber
104// CHECK: %[[FIRST:.*]] = operation "test.first"
105// CHECK: %[[SECOND:.*]] = operation "test.second"
106// CHECK: rewrite %[[FIRST]] {
107// CHECK:   replace %[[FIRST]] with %[[SECOND]]
108Pattern TupleMemberAccessNumber {
109  let firstOp = op<test.first>;
110  let secondOp = op<test.second>(firstOp);
111  let tuple = (firstOp, secondOp);
112  replace tuple.0 with tuple.1;
113}
114
115// -----
116
117// CHECK: pdl.pattern @TupleMemberAccessName
118// CHECK: %[[FIRST:.*]] = operation "test.first"
119// CHECK: %[[SECOND:.*]] = operation "test.second"
120// CHECK: rewrite %[[FIRST]] {
121// CHECK:   replace %[[FIRST]] with %[[SECOND]]
122Pattern TupleMemberAccessName {
123  let firstOp = op<test.first>;
124  let secondOp = op<test.second>(firstOp);
125  let tuple = (first = firstOp, second = secondOp);
126  replace tuple.first with tuple.second;
127}
128
129// -----
130
131//===----------------------------------------------------------------------===//
132// RangeExpr
133//===----------------------------------------------------------------------===//
134
135// CHECK: pdl.pattern @RangeExpr
136// CHECK: %[[ARG:.*]] = operand
137// CHECK: %[[ARGS:.*]] = operands
138// CHECK: %[[TYPE:.*]] = type
139// CHECK: %[[TYPES:.*]] = types
140// CHECK:   range : !pdl.range<value>
141// CHECK:   range %[[ARG]], %[[ARGS]] : !pdl.value, !pdl.range<value>
142// CHECK:   range : !pdl.range<type>
143// CHECK:   range %[[TYPE]], %[[TYPES]] : !pdl.type, !pdl.range<type>
144Pattern RangeExpr {
145  replace op<>(arg: Value, args: ValueRange) -> (type: Type, types: TypeRange)
146    with op<test.op>((), (arg, args)) -> ((), (type, types));
147}
148
149// -----
150
151//===----------------------------------------------------------------------===//
152// TypeExpr
153//===----------------------------------------------------------------------===//
154
155// CHECK: pdl.pattern @TypeExpr
156// CHECK: %[[TYPE:.*]] = type : i32
157// CHECK: operation({{.*}}) -> (%[[TYPE]] : !pdl.type)
158Pattern TypeExpr => erase op<> -> (type<"i32">);
159