159 lines · plain
1// RUN: mlir-pdll %s -I %S -I %S/../../../../include -split-input-file -x mlir | FileCheck %s2 3//===----------------------------------------------------------------------===//4// AttributeExpr5//===----------------------------------------------------------------------===//6 7// CHECK: pdl.pattern @AttrExpr8// CHECK: %[[ATTR:.*]] = attribute = 109// CHECK: operation({{.*}}) {"attr" = %[[ATTR]]}10Pattern AttrExpr => erase op<> { attr = attr<"10"> };11 12// -----13 14//===----------------------------------------------------------------------===//15// CallExpr16//===----------------------------------------------------------------------===//17 18// CHECK: pdl.pattern @TestCallWithArgsAndReturn19// CHECK: %[[ROOT:.*]] = operation20// 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 @TestExternalCall30// CHECK: %[[ROOT:.*]] = operation31// 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 @TestExternalNegatedCall40// CHECK: %[[ROOT:.*]] = operation41// 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// MemberAccessExpr55//===----------------------------------------------------------------------===//56 57// Handle implicit "all" operation results access.58// CHECK: pdl.pattern @OpAllResultMemberAccess59// CHECK: %[[OP0:.*]] = operation60// CHECK: %[[OP0_RES:.*]] = result 0 of %[[OP0]]61// CHECK: %[[OP1:.*]] = operation62// 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 @UnregisteredOpResultIndexing74// 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 @OpResultMemberAccess90// CHECK: %[[OP0:.*]] = operation91// CHECK: %[[RES:.*]] = results 0 of %[[OP0]] -> !pdl.value92// CHECK: %[[RES1:.*]] = results 0 of %[[OP0]] -> !pdl.value93// 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 @TupleMemberAccessNumber104// 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 @TupleMemberAccessName118// 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// RangeExpr133//===----------------------------------------------------------------------===//134 135// CHECK: pdl.pattern @RangeExpr136// CHECK: %[[ARG:.*]] = operand137// CHECK: %[[ARGS:.*]] = operands138// CHECK: %[[TYPE:.*]] = type139// CHECK: %[[TYPES:.*]] = types140// 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// TypeExpr153//===----------------------------------------------------------------------===//154 155// CHECK: pdl.pattern @TypeExpr156// CHECK: %[[TYPE:.*]] = type : i32157// CHECK: operation({{.*}}) -> (%[[TYPE]] : !pdl.type)158Pattern TypeExpr => erase op<> -> (type<"i32">);159