484 lines · plain
1// RUN: mlir-opt %s -transform-interpreter -verify-diagnostics -allow-unregistered-dialect -split-input-file | FileCheck %s2 3// CHECK-DAG: memref.global "private" @[[ALLOC0:alloc.*]] : memref<2x32xf32>4// CHECK-DAG: memref.global "private" @[[ALLOC1:alloc.*]] : memref<2x32xf32>5 6// CHECK-DAG: func.func @func(%[[LB:.*]]: index, %[[UB:.*]]: index)7func.func @func(%lb: index, %ub: index) {8 // CHECK-DAG: scf.forall (%[[ARG0:.*]], %[[ARG1:.*]]) in (%[[LB]], %[[UB]])9 scf.forall (%arg0, %arg1) in (%lb, %ub) {10 // CHECK-DAG: %[[MR0:.*]] = memref.get_global @[[ALLOC0]] : memref<2x32xf32>11 // CHECK-DAG: %[[MR1:.*]] = memref.get_global @[[ALLOC1]] : memref<2x32xf32>12 // CHECK-DAG: memref.store %{{.*}}, %[[MR0]][%{{.*}}, %{{.*}}] : memref<2x32xf32>13 // CHECK-DAG: memref.store %{{.*}}, %[[MR1]][%{{.*}}, %{{.*}}] : memref<2x32xf32>14 %cst = arith.constant 0.0 : f3215 %mr0 = memref.alloca() : memref<2x32xf32>16 %mr1 = memref.alloca() : memref<2x32xf32>17 memref.store %cst, %mr0[%arg0, %arg1] : memref<2x32xf32>18 memref.store %cst, %mr1[%arg0, %arg1] : memref<2x32xf32>19 }20 return21}22 23module attributes {transform.with_named_sequence} {24 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {25 %alloca = transform.structured.match ops{["memref.alloca"]} in %arg026 : (!transform.any_op) -> !transform.op<"memref.alloca">27 %get_global, %global = transform.memref.alloca_to_global %alloca28 : (!transform.op<"memref.alloca">)29 -> (!transform.any_op, !transform.any_op)30 transform.yield31 }32}33 34// -----35 36// CHECK-DAG: #[[$MAP0:.*]] = affine_map<(d0) -> ((d0 floordiv 4) mod 2)>37// CHECK-DAG: #[[$MAP1:.*]] = affine_map<(d0)[s0] -> (d0 + s0)>38 39// CHECK-LABEL: func @multi_buffer40func.func @multi_buffer(%in: memref<16xf32>) {41 // CHECK: %[[A:.*]] = memref.alloc() : memref<2x4xf32>42 // expected-remark @below {{transformed}}43 %tmp = memref.alloc() : memref<4xf32>44 45 // CHECK: %[[C0:.*]] = arith.constant 0 : index46 // CHECK: %[[C4:.*]] = arith.constant 4 : index47 %c0 = arith.constant 0 : index48 %c4 = arith.constant 4 : index49 %c16 = arith.constant 16 : index50 51 // CHECK: scf.for %[[IV:.*]] = %[[C0]]52 scf.for %i0 = %c0 to %c16 step %c4 {53 // CHECK: %[[I:.*]] = affine.apply #[[$MAP0]](%[[IV]])54 // CHECK: %[[SV:.*]] = memref.subview %[[A]][%[[I]], 0] [1, 4] [1, 1] : memref<2x4xf32> to memref<4xf32, strided<[1], offset: ?>>55 %1 = memref.subview %in[%i0] [4] [1] : memref<16xf32> to memref<4xf32, affine_map<(d0)[s0] -> (d0 + s0)>>56 // CHECK: memref.copy %{{.*}}, %[[SV]] : memref<4xf32, #[[$MAP1]]> to memref<4xf32, strided<[1], offset: ?>>57 memref.copy %1, %tmp : memref<4xf32, affine_map<(d0)[s0] -> (d0 + s0)>> to memref<4xf32>58 59 "some_use"(%tmp) : (memref<4xf32>) ->()60 }61 return62}63 64module attributes {transform.with_named_sequence} {65 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {66 %0 = transform.structured.match ops{["memref.alloc"]} in %arg1 : (!transform.any_op) -> !transform.op<"memref.alloc">67 %1 = transform.memref.multibuffer %0 {factor = 2 : i64} : (!transform.op<"memref.alloc">) -> !transform.any_op68 // Verify that the returned handle is usable.69 transform.debug.emit_remark_at %1, "transformed" : !transform.any_op70 transform.yield71 }72}73 74// -----75 76// CHECK-DAG: #[[$MAP0:.*]] = affine_map<(d0) -> ((d0 floordiv 4) mod 2)>77// CHECK-DAG: #[[$MAP1:.*]] = affine_map<(d0)[s0] -> (d0 + s0)>78 79// CHECK-LABEL: func @multi_buffer_on_affine_loop80func.func @multi_buffer_on_affine_loop(%in: memref<16xf32>) {81 // CHECK: %[[A:.*]] = memref.alloc() : memref<2x4xf32>82 // expected-remark @below {{transformed}}83 %tmp = memref.alloc() : memref<4xf32>84 85 // CHECK: %[[C0:.*]] = arith.constant 0 : index86 %c0 = arith.constant 0 : index87 88 // CHECK: affine.for %[[IV:.*]] = 089 affine.for %i0 = 0 to 16 step 4 {90 // CHECK: %[[I:.*]] = affine.apply #[[$MAP0]](%[[IV]])91 // CHECK: %[[SV:.*]] = memref.subview %[[A]][%[[I]], 0] [1, 4] [1, 1] : memref<2x4xf32> to memref<4xf32, strided<[1], offset: ?>>92 %1 = memref.subview %in[%i0] [4] [1] : memref<16xf32> to memref<4xf32, affine_map<(d0)[s0] -> (d0 + s0)>>93 // CHECK: memref.copy %{{.*}}, %[[SV]] : memref<4xf32, #[[$MAP1]]> to memref<4xf32, strided<[1], offset: ?>>94 memref.copy %1, %tmp : memref<4xf32, affine_map<(d0)[s0] -> (d0 + s0)>> to memref<4xf32>95 96 "some_use"(%tmp) : (memref<4xf32>) ->()97 }98 return99}100 101module attributes {transform.with_named_sequence} {102 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {103 %0 = transform.structured.match ops{["memref.alloc"]} in %arg1 : (!transform.any_op) -> !transform.op<"memref.alloc">104 %1 = transform.memref.multibuffer %0 {factor = 2 : i64} : (!transform.op<"memref.alloc">) -> !transform.any_op105 // Verify that the returned handle is usable.106 transform.debug.emit_remark_at %1, "transformed" : !transform.any_op107 transform.yield108 }109}110 111// -----112 113// Trying to use multibuffer on allocs that are used in different loops114// with none dominating the other is going to fail.115// Check that we emit a proper error for that.116func.func @multi_buffer_uses_with_no_loop_dominator(%in: memref<16xf32>, %cond: i1) {117 // expected-error @below {{op failed to multibuffer}}118 %tmp = memref.alloc() : memref<4xf32>119 120 %c0 = arith.constant 0 : index121 %c4 = arith.constant 4 : index122 %c16 = arith.constant 16 : index123 scf.if %cond {124 scf.for %i0 = %c0 to %c16 step %c4 {125 %var = memref.subview %in[%i0] [4] [1] : memref<16xf32> to memref<4xf32, affine_map<(d0)[s0] -> (d0 + s0)>>126 memref.copy %var, %tmp : memref<4xf32, affine_map<(d0)[s0] -> (d0 + s0)>> to memref<4xf32>127 128 "some_use"(%tmp) : (memref<4xf32>) ->()129 }130 }131 132 scf.for %i0 = %c0 to %c16 step %c4 {133 %1 = memref.subview %in[%i0] [4] [1] : memref<16xf32> to memref<4xf32, affine_map<(d0)[s0] -> (d0 + s0)>>134 memref.copy %1, %tmp : memref<4xf32, affine_map<(d0)[s0] -> (d0 + s0)>> to memref<4xf32>135 136 "some_use"(%tmp) : (memref<4xf32>) ->()137 }138 return139}140 141module attributes {transform.with_named_sequence} {142 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {143 %0 = transform.structured.match ops{["memref.alloc"]} in %arg1 : (!transform.any_op) -> !transform.op<"memref.alloc">144 %1 = transform.memref.multibuffer %0 {factor = 2 : i64} : (!transform.op<"memref.alloc">) -> !transform.any_op145 transform.yield146 }147}148 149// -----150 151// Make sure the multibuffer operation is typed so that it only supports152// memref.alloc.153// Check that we emit an error if we try to match something else.154func.func @multi_buffer_reject_alloca(%in: memref<16xf32>, %cond: i1) {155 %tmp = memref.alloca() : memref<4xf32>156 157 %c0 = arith.constant 0 : index158 %c4 = arith.constant 4 : index159 %c16 = arith.constant 16 : index160 scf.if %cond {161 scf.for %i0 = %c0 to %c16 step %c4 {162 %var = memref.subview %in[%i0] [4] [1] : memref<16xf32> to memref<4xf32, affine_map<(d0)[s0] -> (d0 + s0)>>163 memref.copy %var, %tmp : memref<4xf32, affine_map<(d0)[s0] -> (d0 + s0)>> to memref<4xf32>164 165 "some_use"(%tmp) : (memref<4xf32>) ->()166 }167 }168 169 scf.for %i0 = %c0 to %c16 step %c4 {170 %1 = memref.subview %in[%i0] [4] [1] : memref<16xf32> to memref<4xf32, affine_map<(d0)[s0] -> (d0 + s0)>>171 memref.copy %1, %tmp : memref<4xf32, affine_map<(d0)[s0] -> (d0 + s0)>> to memref<4xf32>172 173 "some_use"(%tmp) : (memref<4xf32>) ->()174 }175 return176}177 178module attributes {transform.with_named_sequence} {179 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {180 %0 = transform.structured.match ops{["memref.alloca"]} in %arg1 : (!transform.any_op) -> !transform.op<"memref.alloca">181 // expected-error @below {{'transform.memref.multibuffer' op operand #0 must be Transform IR handle to memref.alloc operations, but got '!transform.op<"memref.alloca">'}}182 %1 = transform.memref.multibuffer %0 {factor = 2 : i64} : (!transform.op<"memref.alloca">) -> !transform.any_op183 transform.yield184 }185}186 187// -----188 189// CHECK-DAG: #[[$MAP0:.*]] = affine_map<(d0) -> ((d0 floordiv 4) mod 2)>190// CHECK-DAG: #[[$MAP1:.*]] = affine_map<(d0)[s0] -> (d0 + s0)>191 192// CHECK-LABEL: func @multi_buffer_one_alloc_with_use_outside_of_loop193// Make sure we manage to apply multi_buffer to the memref that is used in194// the loop (%tmp) and don't error out for the one that is not (%tmp2).195func.func @multi_buffer_one_alloc_with_use_outside_of_loop(%in: memref<16xf32>) {196 // CHECK: %[[A:.*]] = memref.alloc() : memref<2x4xf32>197 // expected-remark @below {{transformed}}198 %tmp = memref.alloc() : memref<4xf32>199 %tmp2 = memref.alloc() : memref<4xf32>200 201 "some_use_outside_of_loop"(%tmp2) : (memref<4xf32>) -> ()202 203 // CHECK: %[[C0:.*]] = arith.constant 0 : index204 // CHECK: %[[C4:.*]] = arith.constant 4 : index205 %c0 = arith.constant 0 : index206 %c4 = arith.constant 4 : index207 %c16 = arith.constant 16 : index208 209 // CHECK: scf.for %[[IV:.*]] = %[[C0]]210 scf.for %i0 = %c0 to %c16 step %c4 {211 // CHECK: %[[I:.*]] = affine.apply #[[$MAP0]](%[[IV]])212 // CHECK: %[[SV:.*]] = memref.subview %[[A]][%[[I]], 0] [1, 4] [1, 1] : memref<2x4xf32> to memref<4xf32, strided<[1], offset: ?>>213 %1 = memref.subview %in[%i0] [4] [1] : memref<16xf32> to memref<4xf32, affine_map<(d0)[s0] -> (d0 + s0)>>214 // CHECK: memref.copy %{{.*}}, %[[SV]] : memref<4xf32, #[[$MAP1]]> to memref<4xf32, strided<[1], offset: ?>>215 memref.copy %1, %tmp : memref<4xf32, affine_map<(d0)[s0] -> (d0 + s0)>> to memref<4xf32>216 217 "some_use"(%tmp) : (memref<4xf32>) ->()218 }219 return220}221 222module attributes {transform.with_named_sequence} {223 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {224 %0 = transform.structured.match ops{["memref.alloc"]} in %arg1 : (!transform.any_op) -> !transform.op<"memref.alloc">225 %1 = transform.memref.multibuffer %0 {factor = 2 : i64} : (!transform.op<"memref.alloc">) -> !transform.any_op226 // Verify that the returned handle is usable.227 transform.debug.emit_remark_at %1, "transformed" : !transform.any_op228 transform.yield229 }230}231 232// -----233 234 235// CHECK-DAG: #[[$MAP0:.*]] = affine_map<(d0) -> ((d0 floordiv 4) mod 2)>236 237// CHECK-LABEL: func @multi_buffer238func.func @multi_buffer_no_analysis(%in: memref<16xf32>) {239 // CHECK: %[[A:.*]] = memref.alloc() : memref<2x4xf32>240 // expected-remark @below {{transformed}}241 %tmp = memref.alloc() : memref<4xf32>242 243 // CHECK: %[[C0:.*]] = arith.constant 0 : index244 // CHECK: %[[C4:.*]] = arith.constant 4 : index245 %c0 = arith.constant 0 : index246 %c4 = arith.constant 4 : index247 %c16 = arith.constant 16 : index248 249 // CHECK: scf.for %[[IV:.*]] = %[[C0]]250 scf.for %i0 = %c0 to %c16 step %c4 {251 // CHECK: %[[I:.*]] = affine.apply #[[$MAP0]](%[[IV]])252 // CHECK: %[[SV:.*]] = memref.subview %[[A]][%[[I]], 0] [1, 4] [1, 1] : memref<2x4xf32> to memref<4xf32, strided<[1], offset: ?>>253 "some_write_read"(%tmp) : (memref<4xf32>) ->()254 }255 return256}257 258module attributes {transform.with_named_sequence} {259 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {260 %0 = transform.structured.match ops{["memref.alloc"]} in %arg1 : (!transform.any_op) -> !transform.op<"memref.alloc">261 %1 = transform.memref.multibuffer %0 {factor = 2 : i64, skip_analysis} : (!transform.op<"memref.alloc">) -> !transform.any_op262 // Verify that the returned handle is usable.263 transform.debug.emit_remark_at %1, "transformed" : !transform.any_op264 transform.yield265 }266}267 268// -----269 270// CHECK-DAG: #[[$MAP0:.*]] = affine_map<(d0) -> ((d0 floordiv 4) mod 2)>271 272// CHECK-LABEL: func @multi_buffer_dealloc273func.func @multi_buffer_dealloc(%in: memref<16xf32>) {274 // CHECK: %[[A:.*]] = memref.alloc() : memref<2x4xf32>275 // expected-remark @below {{transformed}}276 %tmp = memref.alloc() : memref<4xf32>277 278 // CHECK: %[[C0:.*]] = arith.constant 0 : index279 // CHECK: %[[C4:.*]] = arith.constant 4 : index280 %c0 = arith.constant 0 : index281 %c4 = arith.constant 4 : index282 %c16 = arith.constant 16 : index283 284 // CHECK: scf.for %[[IV:.*]] = %[[C0]]285 scf.for %i0 = %c0 to %c16 step %c4 {286 // CHECK: %[[I:.*]] = affine.apply #[[$MAP0]](%[[IV]])287 // CHECK: %[[SV:.*]] = memref.subview %[[A]][%[[I]], 0] [1, 4] [1, 1] : memref<2x4xf32> to memref<4xf32, strided<[1], offset: ?>>288 "some_write_read"(%tmp) : (memref<4xf32>) ->()289 }290 291 // CHECK-NOT: memref.dealloc {{.*}} : memref<4xf32>292 // CHECK: memref.dealloc %[[A]] : memref<2x4xf32>293 memref.dealloc %tmp : memref<4xf32>294 return295}296 297module attributes {transform.with_named_sequence} {298 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {299 %0 = transform.structured.match ops{["memref.alloc"]} in %arg1 : (!transform.any_op) -> !transform.op<"memref.alloc">300 %1 = transform.memref.multibuffer %0 {factor = 2 : i64, skip_analysis} : (!transform.op<"memref.alloc">) -> !transform.any_op301 // Verify that the returned handle is usable.302 transform.debug.emit_remark_at %1, "transformed" : !transform.any_op303 transform.yield304 }305}306 307// -----308 309// CHECK-LABEL: func.func @dead_alloc_escaped310func.func @dead_alloc_escaped() -> memref<8x64xf32, 3> {311 // CHECK: %{{.+}} = memref.alloc312 %0 = memref.alloc() : memref<8x64xf32, 3>313 return %0 : memref<8x64xf32, 3>314}315 316module attributes {transform.with_named_sequence} {317 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {318 %0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op319 transform.memref.erase_dead_alloc_and_stores %0 : (!transform.any_op) -> ()320 transform.yield321 }322}323 324// -----325 326// CHECK-LABEL: func.func @dead_alloc327func.func @dead_alloc() {328 // CHECK-NOT: %{{.+}} = memref.alloc329 %0 = memref.alloc() : memref<8x64xf32, 3>330 %1 = memref.subview %0[0, 0] [8, 4] [1, 1] : memref<8x64xf32, 3> to331 memref<8x4xf32, affine_map<(d0, d1) -> (d0 * 64 + d1)>, 3>332 %c0 = arith.constant 0 : index333 %cst_0 = arith.constant dense<0.000000e+00> : vector<1x4xf32>334 vector.transfer_write %cst_0, %1[%c0, %c0] {in_bounds = [true, true]} :335 vector<1x4xf32>, memref<8x4xf32, affine_map<(d0, d1) -> (d0 * 64 + d1)>, 3>336 return337}338 339module attributes {transform.with_named_sequence} {340 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {341 %0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op342 transform.memref.erase_dead_alloc_and_stores %0 : (!transform.any_op) -> ()343 transform.yield344 }345}346 347// -----348 349// CHECK-LABEL: func.func @dead_alloca350func.func @dead_alloca() {351 // CHECK-NOT: %{{.+}} = memref.alloca352 %0 = memref.alloca() : memref<8x64xf32, 3>353 %1 = memref.subview %0[0, 0] [8, 4] [1, 1] : memref<8x64xf32, 3> to354 memref<8x4xf32, affine_map<(d0, d1) -> (d0 * 64 + d1)>, 3>355 %c0 = arith.constant 0 : index356 %cst_0 = arith.constant dense<0.000000e+00> : vector<1x4xf32>357 vector.transfer_write %cst_0, %1[%c0, %c0] {in_bounds = [true, true]} :358 vector<1x4xf32>, memref<8x4xf32, affine_map<(d0, d1) -> (d0 * 64 + d1)>, 3>359 return360}361 362module attributes {transform.with_named_sequence} {363 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {364 %0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op365 transform.memref.erase_dead_alloc_and_stores %0 : (!transform.any_op) -> ()366 transform.yield367 }368}369 370 371// -----372 373// CHECK-LABEL: @store_to_load374// CHECK-SAME: (%[[ARG:.+]]: vector<4xf32>)375// CHECK-NOT: memref.alloc()376// CHECK-NOT: vector.transfer_write377// CHECK-NOT: vector.transfer_read378// CHECK: return %[[ARG]] : vector<4xf32>379func.func @store_to_load(%arg: vector<4xf32>) -> vector<4xf32> {380 %c0 = arith.constant 0 : index381 %cst_1 = arith.constant 0.000000e+00 : f32382 %alloc = memref.alloc() {alignment = 64 : i64} : memref<64xf32>383 vector.transfer_write %arg, %alloc[%c0] {in_bounds = [true]} : vector<4xf32>, memref<64xf32>384 %r = vector.transfer_read %alloc[%c0], %cst_1 {in_bounds = [true]} : memref<64xf32>, vector<4xf32>385 return %r : vector<4xf32>386}387 388module attributes {transform.with_named_sequence} {389 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {390 %0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op391 transform.memref.erase_dead_alloc_and_stores %0 : (!transform.any_op) -> ()392 transform.yield393 }394}395 396// -----397 398// CHECK-LABEL: @dead_store_through_subview399// CHECK-SAME: (%[[ARG:.+]]: vector<4xf32>)400// CHECK-NOT: memref.alloc()401// CHECK-NOT: vector.transfer_write402func.func @dead_store_through_subview(%arg: vector<4xf32>) {403 %c0 = arith.constant 0 : index404 %alloc = memref.alloc() {alignment = 64 : i64} : memref<64xf32>405 %subview = memref.subview %alloc[%c0] [4] [1] : memref<64xf32> to memref<4xf32, affine_map<(d0)[s0] -> (d0 + s0)>>406 vector.transfer_write %arg, %subview[%c0] {in_bounds = [true]}407 : vector<4xf32>, memref<4xf32, affine_map<(d0)[s0] -> (d0 + s0)>>408 return409}410 411module attributes {transform.with_named_sequence} {412 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {413 %0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op414 transform.memref.erase_dead_alloc_and_stores %0 : (!transform.any_op) -> ()415 transform.yield416 }417}418 419// -----420 421// CHECK-LABEL: @dead_store_through_expand422// CHECK-SAME: (%[[ARG:.+]]: vector<4xf32>)423// CHECK-NOT: memref.alloc()424// CHECK-NOT: vector.transfer_write425func.func @dead_store_through_expand(%arg: vector<4xf32>) {426 %c0 = arith.constant 0 : index427 %alloc = memref.alloc() {alignment = 64 : i64} : memref<64xf32>428 %expand = memref.expand_shape %alloc [[0, 1]] output_shape [16, 4] : memref<64xf32> into memref<16x4xf32>429 vector.transfer_write %arg, %expand[%c0, %c0] {in_bounds = [true]} : vector<4xf32>, memref<16x4xf32>430 return431}432 433module attributes {transform.with_named_sequence} {434 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {435 %0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op436 transform.memref.erase_dead_alloc_and_stores %0 : (!transform.any_op) -> ()437 transform.yield438 }439}440 441// -----442 443// CHECK-LABEL: @dead_store_through_collapse444// CHECK-SAME: (%[[ARG:.+]]: vector<4xf32>)445// CHECK-NOT: memref.alloc()446// CHECK-NOT: vector.transfer_write447func.func @dead_store_through_collapse(%arg: vector<4xf32>) {448 %c0 = arith.constant 0 : index449 %alloc = memref.alloc() {alignment = 64 : i64} : memref<16x4xf32>450 %collapse = memref.collapse_shape %alloc [[0, 1]] : memref<16x4xf32> into memref<64xf32>451 vector.transfer_write %arg, %collapse[%c0] {in_bounds = [true]} : vector<4xf32>, memref<64xf32>452 return453}454 455module attributes {transform.with_named_sequence} {456 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {457 %0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op458 transform.memref.erase_dead_alloc_and_stores %0 : (!transform.any_op) -> ()459 transform.yield460 }461}462 463// -----464 465// CHECK-LABEL: func @lower_to_llvm466// CHECK-NOT: memref.alloc467// CHECK: llvm.call @malloc468func.func @lower_to_llvm() {469 %0 = memref.alloc() : memref<2048xi8>470 return471}472 473module attributes {transform.with_named_sequence} {474 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {475 %0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op476 transform.apply_conversion_patterns to %0 {477 transform.apply_conversion_patterns.dialect_to_llvm "memref"478 } with type_converter {479 transform.apply_conversion_patterns.memref.memref_to_llvm_type_converter480 } {legal_dialects = ["func", "llvm"]} : !transform.any_op481 transform.yield482 }483}484