1// RUN: mlir-opt %s --transform-interpreter -allow-unregistered-dialect --split-input-file --verify-diagnostics 2 3func.func @bar() { 4 // expected-remark @below {{matched op name}} 5 // expected-remark @below {{matched attr name}} 6 %0 = arith.constant {my_attr} 0: i32 7 // expected-remark @below {{matched op name}} 8 %1 = arith.constant 1 : i32 9 return 10} 11 12module attributes {transform.with_named_sequence} { 13 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) { 14 %match_name = transform.structured.match ops{["arith.constant"]} in %arg1 : (!transform.any_op) -> !transform.any_op 15 transform.debug.emit_remark_at %match_name, "matched op name" : !transform.any_op 16 transform.test_consume_operand %match_name : !transform.any_op 17 18 %match_attr = transform.structured.match ops{["arith.constant"]} attributes{my_attr} in %arg1 : (!transform.any_op) -> !transform.any_op 19 transform.debug.emit_remark_at %match_attr, "matched attr name" : !transform.any_op 20 transform.test_consume_operand %match_attr : !transform.any_op 21 transform.yield 22 } 23} 24 25// ----- 26 27func.func @by_type() { 28 %0 = arith.constant 0: i32 29 // expected-remark @below {{matched op name}} 30 %1 = arith.constant 1.0 : f32 31 return 32} 33 34module attributes {transform.with_named_sequence} { 35 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) { 36 %match_name = transform.structured.match 37 ops{["arith.constant"]} filter_result_type = f32 in %arg1 : (!transform.any_op) -> !transform.any_op 38 transform.debug.emit_remark_at %match_name, "matched op name" : !transform.any_op 39 transform.test_consume_operand %match_name : !transform.any_op 40 transform.yield 41 } 42} 43 44// ----- 45 46func.func @by_operand_type() { 47 %c2 = arith.constant 2.0: f32 48 %v = arith.constant 8: i32 49 %r1 = math.fpowi %c2, %v : f32, i32 50 // expected-remark @below {{matched op name}} 51 %r2 = arith.addf %c2, %c2 : f32 52 // expected-remark @below {{matched op name}} 53 %r3 = arith.fptoui %r2 : f32 to i32 54 return 55} 56 57module attributes {transform.with_named_sequence} { 58 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) { 59 %match_name1 = transform.structured.match 60 ops{["arith.fptoui"]} filter_operand_types = [f32] in %arg1 : (!transform.any_op) -> !transform.any_op 61 transform.debug.emit_remark_at %match_name1, "matched op name" : !transform.any_op 62 transform.test_consume_operand %match_name1 : !transform.any_op 63 64 %match_name2 = transform.structured.match 65 ops{["arith.addf"]} filter_operand_types = [f32] in %arg1 : (!transform.any_op) -> !transform.any_op 66 transform.debug.emit_remark_at %match_name2, "matched op name" : !transform.any_op 67 transform.test_consume_operand %match_name2 : !transform.any_op 68 69 %no_match_name1 = transform.structured.match 70 ops{["arith.fptoui"]} filter_operand_types = [i32] in %arg1 : (!transform.any_op) -> !transform.any_op 71 transform.debug.emit_remark_at %no_match_name1, "should not match" : !transform.any_op 72 transform.test_consume_operand %no_match_name1 : !transform.any_op 73 74 %no_match_name2 = transform.structured.match 75 ops{["math.fpowi"]} filter_operand_types = [f32] in %arg1 : (!transform.any_op) -> !transform.any_op 76 transform.debug.emit_remark_at %no_match_name2, "should not match" : !transform.any_op 77 transform.test_consume_operand %no_match_name2 : !transform.any_op 78 transform.yield 79 } 80} 81 82// ----- 83 84func.func @foo(%a: tensor<4x4xf32>, %b: tensor<4x4xf32>, %c: tensor<4x4xf32>) { 85 %c0 = arith.constant 0.0 : f32 86 // expected-remark @below {{tileable}} 87 %r = linalg.fill ins(%c0 : f32) outs(%c : tensor<4x4xf32>) -> tensor<4x4xf32> 88 // expected-remark @below {{tileable}} 89 linalg.matmul ins(%a, %b : tensor<4x4xf32>, tensor<4x4xf32>) outs(%r : tensor<4x4xf32>) -> tensor<4x4xf32> 90 return 91} 92 93module attributes {transform.with_named_sequence} { 94 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) { 95 %matched = transform.structured.match interface{TilingInterface} in %arg0 : (!transform.any_op) -> !transform.any_op 96 transform.debug.emit_remark_at %matched, "tileable" : !transform.any_op 97 transform.yield 98 } 99} 100 101// ----- 102 103#map0 = affine_map<(d0, d1, d2) -> (d0, d1, d2)> 104#map1 = affine_map<(d0, d1, d2) -> (d1, d0, d2)> 105func.func @match_complex_attribute(%arg0: tensor<12x128x32xf32>) 106 -> tensor<128x12x32xf32> { 107 %0 = tensor.empty() : tensor<128x12x32xf32> 108 // expected-remark @below {{matched complex attr}} 109 %1 = linalg.generic {indexing_maps = [#map0, #map1], 110 iterator_types = ["parallel", "parallel", "parallel"]} 111 ins(%arg0 : tensor<12x128x32xf32>) 112 outs(%0 : tensor<128x12x32xf32>) { 113 ^bb0(%arg1: f32, %arg2: f32): 114 linalg.yield %arg1 : f32 115 } -> tensor<128x12x32xf32> 116 return %1 : tensor<128x12x32xf32> 117} 118 119module attributes {transform.with_named_sequence} { 120 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) { 121 %match_attr = transform.structured.match 122 ops{["linalg.generic"]} 123 attributes{iterator_types = [ 124 #linalg.iterator_type<parallel>, 125 #linalg.iterator_type<parallel>, 126 #linalg.iterator_type<parallel>]} 127 in %arg1 : (!transform.any_op) -> !transform.any_op 128 transform.debug.emit_remark_at %match_attr, "matched complex attr" : !transform.any_op 129 transform.test_consume_operand %match_attr : !transform.any_op 130 131 %no_match = transform.structured.match 132 attributes{iterator_types = [ 133 #linalg.iterator_type<parallel>, 134 #linalg.iterator_type<parallel>, 135 #linalg.iterator_type<reduction>]} 136 in %arg1 : (!transform.any_op) -> !transform.any_op 137 %p = transform.num_associations %no_match : (!transform.any_op) -> !transform.param<i64> 138 // expected-remark @below {{0}} 139 transform.debug.emit_param_as_remark %p : !transform.param<i64> 140 transform.yield 141 } 142} 143 144// ----- 145 146func.func private @callee() 147 148func.func @foo(%lb: index, %ub: index, %step: index) { 149 // expected-remark @below {{loop-like}} 150 scf.for %i = %lb to %ub step %step { 151 func.call @callee() : () -> () 152 scf.yield 153 } 154 // expected-remark @below {{loop-like}} 155 scf.parallel (%i) = (%lb) to (%ub) step (%step) { 156 func.call @callee() : () -> () 157 scf.reduce 158 } 159 // expected-remark @below {{loop-like}} 160 scf.forall (%i) in (%ub) { 161 func.call @callee() : () -> () 162 } 163 return 164} 165 166module attributes {transform.with_named_sequence} { 167 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) { 168 %matched = transform.structured.match interface{LoopLikeInterface} in %arg0 : (!transform.any_op) -> !transform.any_op 169 transform.debug.emit_remark_at %matched, "loop-like" : !transform.any_op 170 transform.yield 171 } 172} 173