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