2666 lines · plain
1// RUN: mlir-opt %s --transform-interpreter -allow-unregistered-dialect --split-input-file --verify-diagnostics | FileCheck %s2 3// UNSUPPORTED: target=aarch64-pc-windows-msvc4 5module attributes {transform.with_named_sequence} {6 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {7 // expected-remark @below {{applying transformation}}8 transform.test_transform_op9 transform.yield10 }11}12 13// -----14 15module attributes {transform.with_named_sequence} {16 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {17 %0 = transform.test_produce_self_handle_or_forward_operand { foo = "bar" } : () -> !transform.any_op18 // expected-remark @below {{succeeded}}19 transform.test_consume_operand_of_op_kind_or_fail %0, "transform.test_produce_self_handle_or_forward_operand" : !transform.any_op20 transform.yield21 }22}23 24// -----25 26module attributes {transform.with_named_sequence} {27 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {28 %0 = transform.test_produce_self_handle_or_forward_operand { foo = "bar" } : () -> !transform.any_op29 // expected-error @below {{expected the operand to be associated a payload op of kind transform.sequence got transform.test_produce_self_handle_or_forward_operand}}30 transform.test_consume_operand_of_op_kind_or_fail %0, "transform.sequence" : !transform.any_op31 transform.yield32 }33}34 35// -----36 37// It is okay to have multiple handles to the same payload op as long38// as only one of them is consumed. The expensive checks mode is necessary39// to detect double-consumption.40module attributes {transform.with_named_sequence} {41 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {42 %0 = transform.test_produce_self_handle_or_forward_operand { foo = "bar" } : () -> !transform.any_op43 %1 = transform.test_copy_payload %0 : (!transform.any_op) -> !transform.any_op44 // expected-remark @below {{succeeded}}45 transform.test_consume_operand_of_op_kind_or_fail %0, "transform.test_produce_self_handle_or_forward_operand" : !transform.any_op46 transform.yield47 }48}49 50// -----51 52module attributes {transform.with_named_sequence} {53 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {54 transform.sequence %arg0 : !transform.any_op failures(propagate) {55 ^bb0(%arg1: !transform.any_op):56 // expected-remark @below {{applying transformation "a"}}57 test_transform_op "a"58 // expected-remark @below {{applying transformation "b"}}59 test_transform_op "b"60 // expected-remark @below {{applying transformation "c"}}61 test_transform_op "c"62 }63 // expected-remark @below {{applying transformation "d"}}64 transform.test_transform_op "d"65 // expected-remark @below {{applying transformation "e"}}66 transform.test_transform_op "e"67 transform.yield68 }69}70 71// -----72 73module attributes {transform.with_named_sequence} {74 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {75 %0 = transform.test_produce_self_handle_or_forward_operand : () -> !transform.any_op76 transform.sequence %0 : !transform.any_op failures(propagate) {77 ^bb0(%arg1: !transform.any_op):78 // expected-remark @below {{succeeded}}79 test_consume_operand_of_op_kind_or_fail %arg1, "transform.test_produce_self_handle_or_forward_operand" : !transform.any_op80 }81 transform.yield82 }83}84 85// -----86 87module attributes {transform.with_named_sequence} {88 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {89 %0 = transform.sequence %arg0 : !transform.any_op -> !transform.any_op failures(propagate) {90 ^bb0(%arg1: !transform.any_op):91 %1 = test_produce_self_handle_or_forward_operand : () -> !transform.any_op92 yield %1 : !transform.any_op93 }94 // expected-remark @below {{succeeded}}95 transform.test_consume_operand_of_op_kind_or_fail %0, "transform.test_produce_self_handle_or_forward_operand" : !transform.any_op96 transform.yield97 }98}99 100// -----101 102// expected-remark @below {{parent function}}103func.func @foo() {104 %0 = arith.constant 0 : i32105 return106}107 108// expected-remark @below {{parent function}}109func.func @bar() {110 %0 = arith.constant 0 : i32111 %1 = arith.constant 1 : i32112 return113}114 115module attributes {transform.with_named_sequence} {116 transform.named_sequence @__transform_main(%root: !transform.any_op) {117 transform.with_pdl_patterns %root : !transform.any_op {118 ^bb0(%arg0: !transform.any_op):119 pdl.pattern @const : benefit(1) {120 %r = pdl.types121 %0 = pdl.operation "arith.constant" -> (%r : !pdl.range<type>)122 pdl.rewrite %0 with "transform.dialect"123 }124 125 transform.sequence %arg0 : !transform.any_op failures(propagate) {126 ^bb1(%arg1: !transform.any_op):127 %f = pdl_match @const in %arg1 : (!transform.any_op) -> !transform.any_op128 %m = get_parent_op %f {isolated_from_above} : (!transform.any_op) -> !transform.any_op129 transform.debug.emit_remark_at %m, "parent function" : !transform.any_op130 }131 }132 transform.yield133 }134}135 136// -----137 138func.func @test_get_nth_parent() {139 "test.foo"() ({140 // expected-remark @below{{2nd parent}}141 "test.foo"() ({142 "test.qux"() ({143 // expected-remark @below{{1st parent}}144 "test.foo"() ({145 "test.bar"() : () -> ()146 }) : () -> ()147 }) : () -> ()148 }) : () -> ()149 }) : () -> ()150}151 152module attributes {transform.with_named_sequence} {153 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {154 %f = transform.structured.match ops{["test.bar"]} in %arg0 : (!transform.any_op) -> !transform.any_op155 %parent = transform.get_parent_op %f {nth_parent = 1, op_name = "test.foo"} : (!transform.any_op) -> !transform.any_op156 transform.debug.emit_remark_at %parent, "1st parent" : !transform.any_op157 %parent2 = transform.get_parent_op %f {nth_parent = 2, op_name = "test.foo"} : (!transform.any_op) -> !transform.any_op158 transform.debug.emit_remark_at %parent2, "2nd parent" : !transform.any_op159 transform.yield160 }161}162 163// -----164 165func.func @foo() {166 %0 = arith.constant 0 : i32167 return168}169 170module attributes {transform.with_named_sequence} {171 transform.named_sequence @__transform_main(%root: !transform.any_op) {172 transform.with_pdl_patterns %root : !transform.any_op {173 ^bb0(%arg0: !transform.any_op):174 pdl.pattern @match_func : benefit(1) {175 %0 = pdl.operands176 %1 = pdl.types177 %2 = pdl.operation "func.func"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)178 pdl.rewrite %2 with "transform.dialect"179 }180 181 transform.sequence %arg0 : !transform.any_op failures(propagate) {182 ^bb1(%arg1: !transform.any_op):183 // This is necessary to run the transformation on something other than the184 // top-level module, "alternatives" cannot be run on that.185 %0 = pdl_match @match_func in %arg1 : (!transform.any_op) -> !transform.any_op186 transform.alternatives %0 : !transform.any_op {187 ^bb2(%arg2: !transform.any_op):188 %1 = transform.test_produce_self_handle_or_forward_operand : () -> !transform.any_op189 // This operation fails, which triggers the next alternative without190 // reporting the error.191 transform.test_consume_operand_of_op_kind_or_fail %1, "transform.sequence" : !transform.any_op192 }, {193 ^bb2(%arg2: !transform.any_op):194 %1 = transform.test_produce_self_handle_or_forward_operand : () -> !transform.any_op195 // expected-remark @below {{succeeded}}196 transform.test_consume_operand_of_op_kind_or_fail %1, "transform.test_produce_self_handle_or_forward_operand" : !transform.any_op197 }198 }199 }200 transform.yield201 }202}203 204// -----205 206func.func private @bar()207 208func.func @foo() {209 call @bar() : () -> ()210 return211}212 213module attributes {transform.with_named_sequence} {214 transform.named_sequence @__transform_main(%root: !transform.any_op) {215 transform.with_pdl_patterns %root : !transform.any_op {216 ^bb0(%arg0: !transform.any_op):217 pdl.pattern @match_call : benefit(1) {218 %0 = pdl.operands219 %1 = pdl.types220 %2 = pdl.operation "func.call"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)221 pdl.rewrite %2 with "transform.dialect"222 }223 224 transform.sequence %arg0 : !transform.any_op failures(propagate) {225 ^bb1(%arg1: !transform.any_op):226 %0 = pdl_match @match_call in %arg1 : (!transform.any_op) -> !transform.any_op227 %1 = get_parent_op %0 {isolated_from_above} : (!transform.any_op) -> !transform.any_op228 // expected-error @below {{all alternatives failed}}229 transform.alternatives %1 : !transform.any_op {230 ^bb2(%arg2: !transform.any_op):231 %2 = transform.pdl_match @match_call in %arg2 : (!transform.any_op) -> !transform.any_op232 // expected-remark @below {{applying}}233 transform.test_emit_remark_and_erase_operand %2, "applying" {fail_after_erase} : !transform.any_op234 }235 }236 }237 transform.yield238 }239}240 241// -----242 243func.func private @bar()244 245func.func @foo() {246 // expected-remark @below {{still here}}247 call @bar() : () -> ()248 return249}250 251module attributes {transform.with_named_sequence} {252 transform.named_sequence @__transform_main(%root: !transform.any_op) {253 transform.with_pdl_patterns %root : !transform.any_op {254 ^bb0(%arg0: !transform.any_op):255 pdl.pattern @match_call : benefit(1) {256 %0 = pdl.operands257 %1 = pdl.types258 %2 = pdl.operation "func.call"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)259 pdl.rewrite %2 with "transform.dialect"260 }261 262 transform.sequence %arg0 : !transform.any_op failures(propagate) {263 ^bb1(%arg1: !transform.any_op):264 %0 = pdl_match @match_call in %arg1 : (!transform.any_op) -> !transform.any_op265 %1 = get_parent_op %0 {isolated_from_above} : (!transform.any_op) -> !transform.any_op266 transform.alternatives %1 : !transform.any_op {267 ^bb2(%arg2: !transform.any_op):268 %2 = transform.pdl_match @match_call in %arg2 : (!transform.any_op) -> !transform.any_op269 // expected-remark @below {{applying}}270 transform.test_emit_remark_and_erase_operand %2, "applying" {fail_after_erase} : !transform.any_op271 }, {272 ^bb2(%arg2: !transform.any_op):273 %2 = transform.pdl_match @match_call in %arg2 : (!transform.any_op) -> !transform.any_op274 transform.debug.emit_remark_at %2, "still here" : !transform.any_op275 // This alternative succeeds.276 }, {277 ^bb2(%arg2: !transform.any_op):278 // This alternative is never run, so we must not have a remark here.279 %2 = transform.pdl_match @match_call in %arg2 : (!transform.any_op) -> !transform.any_op280 transform.test_emit_remark_and_erase_operand %2, "should not happen" {fail_after_erase} : !transform.any_op281 }282 }283 }284 transform.yield285 }286}287 288// -----289 290func.func private @bar()291 292func.func @erase_call() {293 call @bar() : () -> ()294 return295}296 297module attributes {transform.with_named_sequence} {298 transform.named_sequence @__transform_main(%root: !transform.any_op) {299 transform.with_pdl_patterns %root : !transform.any_op {300 ^bb0(%arg0: !transform.any_op):301 pdl.pattern @match_call : benefit(1) {302 %0 = pdl.operands303 %1 = pdl.types304 %2 = pdl.operation "func.call"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)305 pdl.rewrite %2 with "transform.dialect"306 }307 308 transform.sequence %arg0 : !transform.any_op failures(propagate) {309 ^bb1(%arg1: !transform.any_op):310 %0 = pdl_match @match_call in %arg1 : (!transform.any_op) -> !transform.any_op311 %1 = get_parent_op %0 {isolated_from_above} : (!transform.any_op) -> !transform.any_op312 transform.alternatives %1 : !transform.any_op {313 ^bb2(%arg2: !transform.any_op):314 %2 = transform.pdl_match @match_call in %arg2 : (!transform.any_op) -> !transform.any_op315 // expected-remark @below {{applying}}316 transform.test_emit_remark_and_erase_operand %2, "applying" {fail_after_erase} : !transform.any_op317 }, {318 ^bb2(%arg2: !transform.any_op):319 %2 = transform.pdl_match @match_call in %arg2 : (!transform.any_op) -> !transform.any_op320 // expected-remark @below {{applying second time}}321 transform.test_emit_remark_and_erase_operand %2, "applying second time" : !transform.any_op322 }323 }324 }325 transform.yield326 }327}328 329// -----330 331func.func private @bar()332 333func.func @foo() {334 call @bar() : () -> ()335 return336}337 338module attributes {transform.with_named_sequence} {339 transform.named_sequence @__transform_main(%root: !transform.any_op) {340 transform.with_pdl_patterns %root : !transform.any_op {341 ^bb0(%arg0: !transform.any_op):342 pdl.pattern @match_call : benefit(1) {343 %0 = pdl.operands344 %1 = pdl.types345 %2 = pdl.operation "func.call"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)346 pdl.rewrite %2 with "transform.dialect"347 }348 349 transform.sequence %arg0 : !transform.any_op failures(propagate) {350 ^bb1(%arg1: !transform.any_op):351 %0 = pdl_match @match_call in %arg1 : (!transform.any_op) -> !transform.any_op352 %1 = get_parent_op %0 {isolated_from_above} : (!transform.any_op) -> !transform.any_op353 %2 = transform.alternatives %1 : !transform.any_op -> !transform.any_op {354 ^bb2(%arg2: !transform.any_op):355 %3 = transform.pdl_match @match_call in %arg2 : (!transform.any_op) -> !transform.any_op356 // expected-remark @below {{applying}}357 transform.test_emit_remark_and_erase_operand %3, "applying" {fail_after_erase} : !transform.any_op358 %4 = transform.test_produce_self_handle_or_forward_operand %3 : (!transform.any_op) -> !transform.any_op359 transform.yield %4 : !transform.any_op360 }, {361 ^bb2(%arg2: !transform.any_op):362 %4 = transform.test_produce_self_handle_or_forward_operand : () -> !transform.any_op363 transform.yield %4 : !transform.any_op364 }365 // The first alternative failed, so the returned value is taken from the366 // second alternative, associated test_produce_self_handle_or_forward_operand rather367 // than pdl_match.368 // expected-remark @below {{succeeded}}369 transform.test_consume_operand_of_op_kind_or_fail %2, "transform.test_produce_self_handle_or_forward_operand" : !transform.any_op370 }371 }372 transform.yield373 }374}375 376// -----377 378// expected-note @below {{scope}}379module attributes {transform.with_named_sequence} {380 func.func @foo() {381 %0 = arith.constant 0 : i32382 return383 }384 385 func.func @bar() {386 %0 = arith.constant 0 : i32387 %1 = arith.constant 1 : i32388 return389 }390 391 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {392 // expected-error @below {{scope must not contain the transforms being applied}}393 transform.alternatives %arg1 : !transform.any_op {394 ^bb2(%arg2: !transform.any_op):395 %0 = transform.test_produce_self_handle_or_forward_operand : () -> !transform.any_op396 transform.test_consume_operand_of_op_kind_or_fail %0, "transform.sequence" : !transform.any_op397 }, {398 ^bb2(%arg2: !transform.any_op):399 %0 = transform.test_produce_self_handle_or_forward_operand : () -> !transform.any_op400 transform.test_consume_operand_of_op_kind_or_fail %0, "transform.test_produce_self_handle_or_forward_operand" : !transform.any_op401 }402 transform.yield403 }404}405 406// -----407 408func.func @foo(%arg0: index, %arg1: index, %arg2: index) {409 // expected-note @below {{scope}}410 scf.for %i = %arg0 to %arg1 step %arg2 {411 %0 = arith.constant 0 : i32412 }413 return414}415 416module attributes {transform.with_named_sequence} {417 transform.named_sequence @__transform_main(%root: !transform.any_op) {418 transform.with_pdl_patterns %root : !transform.any_op {419 ^bb0(%arg0: !transform.any_op):420 pdl.pattern @match_const : benefit(1) {421 %0 = pdl.operands422 %1 = pdl.types423 %2 = pdl.operation "arith.constant"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)424 pdl.rewrite %2 with "transform.dialect"425 }426 427 428 sequence %arg0 : !transform.any_op failures(propagate) {429 ^bb1(%arg1: !transform.any_op):430 %0 = transform.pdl_match @match_const in %arg1 : (!transform.any_op) -> !transform.any_op431 %1 = transform.get_parent_op %0 {op_name = "scf.for"} : (!transform.any_op) -> !transform.any_op432 // expected-error @below {{only isolated-from-above ops can be alternative scopes}}433 alternatives %1 : !transform.any_op {434 ^bb2(%arg2: !transform.any_op):435 }436 }437 }438 transform.yield439 }440}441// -----442 443func.func @foo() {444 // expected-note @below {{when applied to this op}}445 "op" () : () -> ()446 return447}448 449module attributes {transform.with_named_sequence} {450 transform.named_sequence @__transform_main(%root: !transform.any_op) {451 transform.with_pdl_patterns %root : !transform.any_op {452 ^bb0(%arg0: !transform.any_op):453 pdl.pattern @some : benefit(1) {454 %0 = pdl.operands455 %1 = pdl.types456 %2 = pdl.operation "op"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)457 pdl.rewrite %2 with "transform.dialect"458 }459 460 transform.sequence %arg0 : !transform.any_op failures(propagate) {461 ^bb0(%arg1: !transform.any_op):462 %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op463 // expected-error @below {{application of transform.test_wrong_number_of_results expected to produce 3 results (actually produced 1).}}464 // expected-note @below {{if you need variadic results, consider a generic `apply` instead of the specialized `applyToOne`.}}465 transform.test_wrong_number_of_results %0 : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op)466 }467 }468 transform.yield469 }470}471 472// -----473 474func.func @foo() {475 "op" () : () -> ()476 // expected-note @below {{when applied to this op}}477 "op" () : () -> ()478 return479}480 481module attributes {transform.with_named_sequence} {482 transform.named_sequence @__transform_main(%root: !transform.any_op) {483 transform.with_pdl_patterns %root : !transform.any_op {484 ^bb0(%arg0: !transform.any_op):485 pdl.pattern @some : benefit(1) {486 %0 = pdl.operands487 %1 = pdl.types488 %2 = pdl.operation "op"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)489 pdl.rewrite %2 with "transform.dialect"490 }491 492 transform.sequence %arg0 : !transform.any_op failures(propagate) {493 ^bb0(%arg1: !transform.any_op):494 %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op495 // expected-error @below {{application of transform.test_wrong_number_of_multi_results expected to produce 1 results (actually produced 0)}}496 // expected-note @below {{if you need variadic results, consider a generic `apply` instead of the specialized `applyToOne`.}}497 transform.test_wrong_number_of_multi_results %0 : (!transform.any_op) -> (!transform.any_op)498 }499 }500 transform.yield501 }502}503 504// -----505 506func.func @foo() {507 "op" () : () -> ()508 "op" () : () -> ()509 "op" () : () -> ()510 return511}512 513module attributes {transform.with_named_sequence} {514 transform.named_sequence @__transform_main(%root: !transform.any_op) {515 transform.with_pdl_patterns %root : !transform.any_op {516 ^bb0(%arg0: !transform.any_op):517 pdl.pattern @some : benefit(1) {518 %0 = pdl.operands519 %1 = pdl.types520 %2 = pdl.operation "op"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)521 pdl.rewrite %2 with "transform.dialect"522 }523 524 transform.sequence %arg0 : !transform.any_op failures(propagate) {525 ^bb0(%arg1: !transform.any_op):526 %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op527 // Transform matches 3 ops and produces 2 results.528 %1:2 = transform.test_correct_number_of_multi_results %0 : (!transform.any_op) -> (!transform.any_op, !transform.any_op)529 }530 }531 transform.yield532 }533}534 535// -----536 537func.func @foo() {538 "wrong_op_name" () : () -> ()539 return540}541 542module attributes {transform.with_named_sequence} {543 transform.named_sequence @__transform_main(%root: !transform.any_op) {544 transform.with_pdl_patterns %root : !transform.any_op {545 ^bb0(%arg0: !transform.any_op):546 pdl.pattern @some : benefit(1) {547 %0 = pdl.operands548 %1 = pdl.types549 %2 = pdl.operation "op"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)550 pdl.rewrite %2 with "transform.dialect"551 }552 553 transform.sequence %arg0 : !transform.any_op failures(propagate) {554 ^bb0(%arg1: !transform.any_op):555 %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op556 // Transform fails to match any but still produces 2 results.557 %1:2 = transform.test_correct_number_of_multi_results %0 : (!transform.any_op) -> (!transform.any_op, !transform.any_op)558 }559 }560 transform.yield561 }562}563 564// -----565 566// This should not fail.567 568func.func @foo() {569 "op" () : () -> ()570 return571}572 573module attributes {transform.with_named_sequence} {574 transform.named_sequence @__transform_main(%root: !transform.any_op) {575 transform.with_pdl_patterns %root : !transform.any_op {576 ^bb0(%arg0: !transform.any_op):577 pdl.pattern @some : benefit(1) {578 %0 = pdl.operands579 %1 = pdl.types580 %2 = pdl.operation "op"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)581 pdl.rewrite %2 with "transform.dialect"582 }583 584 transform.sequence %arg0 : !transform.any_op failures(propagate) {585 ^bb0(%arg1: !transform.any_op):586 %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op587 transform.test_mixed_null_and_non_null_results %0 : (!transform.any_op) -> (!transform.any_op, !transform.any_op)588 }589 }590 transform.yield591 }592}593 594// -----595 596// Expecting to match all operations by merging the handles that matched addi597// and subi separately.598func.func @foo(%arg0: index) {599 // expected-remark @below {{matched}}600 %0 = arith.addi %arg0, %arg0 : index601 // expected-remark @below {{matched}}602 %1 = arith.subi %arg0, %arg0 : index603 // expected-remark @below {{matched}}604 %2 = arith.addi %0, %1 : index605 return606}607 608module attributes {transform.with_named_sequence} {609 transform.named_sequence @__transform_main(%root: !transform.any_op) {610 transform.with_pdl_patterns %root : !transform.any_op {611 ^bb0(%arg0: !transform.any_op):612 pdl.pattern @addi : benefit(1) {613 %0 = pdl.operands614 %1 = pdl.types615 %2 = pdl.operation "arith.addi"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)616 pdl.rewrite %2 with "transform.dialect"617 }618 pdl.pattern @subi : benefit(1) {619 %0 = pdl.operands620 %1 = pdl.types621 %2 = pdl.operation "arith.subi"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)622 pdl.rewrite %2 with "transform.dialect"623 }624 625 transform.sequence %arg0 : !transform.any_op failures(propagate) {626 ^bb0(%arg1: !transform.any_op):627 %0 = pdl_match @addi in %arg1 : (!transform.any_op) -> !transform.any_op628 %1 = pdl_match @subi in %arg1 : (!transform.any_op) -> !transform.any_op629 %2 = merge_handles %0, %1 : !transform.any_op630 transform.debug.emit_remark_at %2, "matched" : !transform.any_op631 }632 }633 transform.yield634 }635}636 637// -----638 639func.func @foo(%arg0: index) {640 %0 = arith.addi %arg0, %arg0 : index641 return642}643 644module attributes {transform.with_named_sequence} {645 transform.named_sequence @__transform_main(%root: !transform.any_op) {646 transform.with_pdl_patterns %root : !transform.any_op {647 ^bb0(%arg0: !transform.any_op):648 pdl.pattern @addi : benefit(1) {649 %0 = pdl.operands650 %1 = pdl.types651 %2 = pdl.operation "arith.addi"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)652 pdl.rewrite %2 with "transform.dialect"653 }654 655 transform.sequence %arg0 : !transform.any_op failures(propagate) {656 ^bb0(%arg1: !transform.any_op):657 %0 = pdl_match @addi in %arg1 : (!transform.any_op) -> !transform.any_op658 %1 = pdl_match @addi in %arg1 : (!transform.any_op) -> !transform.any_op659 %2 = merge_handles deduplicate %0, %1 : !transform.any_op660 %3 = num_associations %2 : (!transform.any_op) -> !transform.param<i64>661 // expected-remark @below {{1}}662 transform.debug.emit_param_as_remark %3 : !transform.param<i64>663 }664 }665 transform.yield666 }667}668 669// -----670 671func.func @foo() {672 "op" () { target_me } : () -> ()673 // expected-note @below {{when applied to this op}}674 "op" () : () -> ()675 return676}677 678module attributes {transform.with_named_sequence} {679 transform.named_sequence @__transform_main(%root: !transform.any_op) {680 transform.with_pdl_patterns %root : !transform.any_op {681 ^bb0(%arg0: !transform.any_op):682 pdl.pattern @some : benefit(1) {683 %0 = pdl.operands684 %1 = pdl.types685 %2 = pdl.operation "op"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)686 pdl.rewrite %2 with "transform.dialect"687 }688 689 transform.sequence %arg0 : !transform.any_op failures(propagate) {690 ^bb0(%arg1: !transform.any_op):691 %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op692 // expected-error @below {{failed to apply}}693 transform.test_mixed_success_and_silenceable %0 : !transform.any_op694 }695 }696 transform.yield697 }698}699 700// -----701 702func.func @foo() {703 "op" () : () -> ()704 return705}706 707module attributes {transform.with_named_sequence} {708 transform.named_sequence @__transform_main(%root: !transform.any_op) {709 transform.with_pdl_patterns %root : !transform.any_op {710 ^bb0(%arg0: !transform.any_op):711 pdl.pattern @some : benefit(1) {712 %0 = pdl.operands713 %1 = pdl.types714 %2 = pdl.operation "op"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)715 pdl.rewrite %2 with "transform.dialect"716 }717 718 transform.sequence %arg0 : !transform.any_op failures(suppress) {719 ^bb0(%arg1: !transform.any_op):720 %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op721 // Not expecting error here because we are suppressing it.722 // expected-remark @below {{foo}}723 test_emit_remark_and_erase_operand %0, "foo" {fail_after_erase} : !transform.any_op724 }725 }726 transform.yield727 }728}729 730// -----731 732func.func @foo() {733 "op" () : () -> ()734 return735}736 737module attributes {transform.with_named_sequence} {738 transform.named_sequence @__transform_main(%root: !transform.any_op) {739 transform.with_pdl_patterns %root : !transform.any_op {740 ^bb0(%arg0: !transform.any_op):741 pdl.pattern @some : benefit(1) {742 %0 = pdl.operands743 %1 = pdl.types744 %2 = pdl.operation "op"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)745 pdl.rewrite %2 with "transform.dialect"746 }747 748 transform.sequence %arg0 : !transform.any_op failures(propagate) {749 ^bb0(%arg1: !transform.any_op):750 %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op751 // expected-error @below {{silenceable error}}752 // expected-remark @below {{foo}}753 test_emit_remark_and_erase_operand %0, "foo" {fail_after_erase} : !transform.any_op754 }755 }756 transform.yield757 }758}759 760 761// -----762 763module attributes {transform.with_named_sequence} {764 func.func private @foo()765 func.func private @bar()766 767 transform.named_sequence @__transform_main(%root: !transform.any_op) {768 transform.with_pdl_patterns %root : !transform.any_op {769 770 ^bb0(%arg0: !transform.any_op):771 pdl.pattern @func : benefit(1) {772 %0 = pdl.operands773 %1 = pdl.types774 %2 = pdl.operation "func.func"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)775 pdl.rewrite %2 with "transform.dialect"776 }777 778 transform.sequence %arg0 : !transform.any_op failures(propagate) {779 ^bb0(%arg1: !transform.any_op):780 %0 = pdl_match @func in %arg1 : (!transform.any_op) -> !transform.any_op781 %1 = replicate num(%0) %arg1 : !transform.any_op, !transform.any_op782 %p = num_associations %1 : (!transform.any_op) -> !transform.param<i64>783 // expected-remark @below {{2}}784 transform.debug.emit_param_as_remark %p : !transform.param<i64>785 %2 = replicate num(%0) %1 : !transform.any_op, !transform.any_op786 %p2 = num_associations %2 : (!transform.any_op) -> !transform.param<i64>787 // expected-remark @below {{4}}788 transform.debug.emit_param_as_remark %p2 : !transform.param<i64>789 }790 }791 transform.yield792 }793}794 795// -----796 797func.func @bar() {798 // expected-remark @below {{transform applied}}799 %0 = arith.constant 0 : i32800 // expected-remark @below {{transform applied}}801 %1 = arith.constant 1 : i32802 return803}804 805module attributes {transform.with_named_sequence} {806 transform.named_sequence @__transform_main(%root: !transform.any_op) {807 transform.with_pdl_patterns %root : !transform.any_op {808 ^bb0(%arg0: !transform.any_op):809 pdl.pattern @const : benefit(1) {810 %r = pdl.types811 %0 = pdl.operation "arith.constant" -> (%r : !pdl.range<type>)812 pdl.rewrite %0 with "transform.dialect"813 }814 815 transform.sequence %arg0 : !transform.any_op failures(propagate) {816 ^bb1(%arg1: !transform.any_op):817 %f = pdl_match @const in %arg1 : (!transform.any_op) -> !transform.any_op818 transform.foreach %f : !transform.any_op {819 ^bb2(%arg2: !transform.any_op):820 %p = transform.num_associations %arg2 : (!transform.any_op) -> !transform.param<i64>821 // expected-remark @below {{1}}822 transform.debug.emit_param_as_remark %p : !transform.param<i64>823 transform.debug.emit_remark_at %arg2, "transform applied" : !transform.any_op824 }825 }826 }827 transform.yield828 }829}830 831// -----832 833module attributes { transform.with_named_sequence } {834 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {835 %0 = transform.structured.match ops{["linalg.matmul"]} in %arg0 : (!transform.any_op) -> !transform.any_op836 %results, %types = transform.foreach %0 : !transform.any_op -> !transform.any_value, !transform.any_param {837 ^bb0(%op0 : !transform.any_op):838 %result = transform.get_result %op0[0] : (!transform.any_op) -> !transform.any_value839 %type = transform.get_type elemental %result : (!transform.any_value) -> !transform.any_param840 transform.yield %result, %type : !transform.any_value, !transform.any_param841 }842 transform.debug.emit_remark_at %results, "result selected" : !transform.any_value843 transform.debug.emit_param_as_remark %types, "elemental types" at %0 : !transform.any_param, !transform.any_op844 845 transform.yield846 }847}848 849func.func @payload(%lhs: tensor<10x20xf16>,850 %rhs: tensor<20x15xf32>) -> (tensor<10x15xf64>, tensor<10x15xf32>) {851 %cst64 = arith.constant 0.0 : f64852 %empty64 = tensor.empty() : tensor<10x15xf64>853 %fill64 = linalg.fill ins(%cst64 : f64) outs(%empty64 : tensor<10x15xf64>) -> tensor<10x15xf64>854 // expected-remark @below {{result selected}}855 // expected-note @below {{value handle points to an op result #0}}856 // expected-remark @below {{elemental types f64, f32}}857 %result64 = linalg.matmul ins(%lhs, %rhs: tensor<10x20xf16>, tensor<20x15xf32>)858 outs(%fill64: tensor<10x15xf64>) -> tensor<10x15xf64>859 860 %cst32 = arith.constant 0.0 : f32861 %empty32 = tensor.empty() : tensor<10x15xf32>862 %fill32 = linalg.fill ins(%cst32 : f32) outs(%empty32 : tensor<10x15xf32>) -> tensor<10x15xf32>863 // expected-remark @below {{result selected}}864 // expected-note @below {{value handle points to an op result #0}}865 // expected-remark @below {{elemental types f64, f32}}866 %result32 = linalg.matmul ins(%lhs, %rhs: tensor<10x20xf16>, tensor<20x15xf32>)867 outs(%fill32: tensor<10x15xf32>) -> tensor<10x15xf32>868 869 return %result64, %result32 : tensor<10x15xf64>, tensor<10x15xf32>870 871}872 873// -----874 875func.func @two_const_ops() {876 %0 = arith.constant 0 : index877 %1 = arith.constant 1 : index878 return879}880 881module attributes {transform.with_named_sequence} {882 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {883 %two_ops = transform.structured.match ops{["arith.constant"]} in %arg1 : (!transform.any_op) -> !transform.any_op884 %one_param = transform.param.constant 1 : i32 -> !transform.test_dialect_param885 // expected-error @below {{prior targets' payload size (2) differs from payload size (1) of target}}886 transform.foreach %two_ops, %one_param : !transform.any_op, !transform.test_dialect_param {887 ^bb2(%op: !transform.any_op, %param: !transform.test_dialect_param):888 }889 transform.yield890 }891}892 893// -----894 895func.func @one_const_op() {896 %0 = arith.constant 0 : index897 return898}899 900module attributes {transform.with_named_sequence} {901 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {902 %one_op = transform.structured.match ops{["arith.constant"]} in %arg1 : (!transform.any_op) -> !transform.any_op903 %one_val = transform.test_produce_value_handle_to_self_operand %one_op : (!transform.any_op) -> !transform.any_value904 %param_one = transform.param.constant 1 : i32 -> !transform.test_dialect_param905 %param_two = transform.param.constant 2 : i32 -> !transform.test_dialect_param906 %two_params = transform.merge_handles %param_one, %param_two : !transform.test_dialect_param907 908 // expected-error @below {{prior targets' payload size (1) differs from payload size (2) of target}}909 transform.foreach %one_val, %one_op, %two_params : !transform.any_value, !transform.any_op, !transform.test_dialect_param {910 ^bb2(%val: !transform.any_value, %op: !transform.any_op, %param: !transform.test_dialect_param):911 }912 transform.yield913 }914}915 916// -----917 918// CHECK-LABEL: func @consume_in_foreach()919// CHECK-NEXT: return920func.func @consume_in_foreach() {921 %0 = arith.constant 0 : index922 %1 = arith.constant 1 : index923 %2 = arith.constant 2 : index924 %3 = arith.constant 3 : index925 return926}927 928module attributes {transform.with_named_sequence} {929 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {930 %f = transform.structured.match ops{["arith.constant"]} in %arg1 : (!transform.any_op) -> !transform.any_op931 transform.foreach %f : !transform.any_op {932 ^bb2(%arg2: !transform.any_op):933 // expected-remark @below {{erasing}}934 transform.test_emit_remark_and_erase_operand %arg2, "erasing" : !transform.any_op935 }936 transform.yield937 }938}939 940// -----941 942func.func @bar() {943 scf.execute_region {944 // expected-remark @below {{transform applied}}945 %0 = arith.constant 0 : i32946 scf.yield947 }948 949 scf.execute_region {950 // expected-remark @below {{transform applied}}951 %1 = arith.constant 1 : i32952 // expected-remark @below {{transform applied}}953 %2 = arith.constant 2 : i32954 scf.yield955 }956 957 return958}959 960module attributes {transform.with_named_sequence} {961 transform.named_sequence @__transform_main(%root: !transform.any_op) {962 transform.with_pdl_patterns %root : !transform.any_op {963 ^bb0(%arg0: !transform.any_op):964 pdl.pattern @const : benefit(1) {965 %r = pdl.types966 %0 = pdl.operation "arith.constant" -> (%r : !pdl.range<type>)967 pdl.rewrite %0 with "transform.dialect"968 }969 970 pdl.pattern @execute_region : benefit(1) {971 %r = pdl.types972 %0 = pdl.operation "scf.execute_region" -> (%r : !pdl.range<type>)973 pdl.rewrite %0 with "transform.dialect"974 }975 976 transform.sequence %arg0 : !transform.any_op failures(propagate) {977 ^bb1(%arg1: !transform.any_op):978 %f = pdl_match @execute_region in %arg1 : (!transform.any_op) -> !transform.any_op979 %results = transform.foreach %f : !transform.any_op -> !transform.any_op {980 ^bb2(%arg2: !transform.any_op):981 %g = transform.pdl_match @const in %arg2 : (!transform.any_op) -> !transform.any_op982 transform.yield %g : !transform.any_op983 }984 985 %p = transform.num_associations %results : (!transform.any_op) -> !transform.param<i64>986 // expected-remark @below {{3}}987 transform.debug.emit_param_as_remark %p : !transform.param<i64>988 transform.debug.emit_remark_at %results, "transform applied" : !transform.any_op989 }990 }991 transform.yield992 }993}994 995// -----996 997func.func @get_parent_for_op_no_loop(%arg0: index, %arg1: index) {998 // expected-remark @below {{found muli}}999 %0 = arith.muli %arg0, %arg1 : index1000 arith.addi %0, %arg1 : index1001 return1002}1003 1004module attributes {transform.with_named_sequence} {1005 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {1006 %addi = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op1007 %muli = transform.get_producer_of_operand %addi[0] : (!transform.any_op) -> !transform.any_op1008 transform.debug.emit_remark_at %muli, "found muli" : !transform.any_op1009 transform.yield1010 }1011}1012 1013// -----1014 1015func.func @get_parent_for_op_no_loop(%arg0: index, %arg1: index) {1016 // expected-note @below {{target op}}1017 %0 = arith.muli %arg0, %arg1 : index1018 return1019}1020 1021module attributes {transform.with_named_sequence} {1022 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {1023 %muli = transform.structured.match ops{["arith.muli"]} in %arg1 : (!transform.any_op) -> !transform.any_op1024 // expected-error @below {{could not find a producer for operand number: 0 of}}1025 %bbarg = transform.get_producer_of_operand %muli[0] : (!transform.any_op) -> !transform.any_op1026 transform.yield1027 }1028}1029 1030// -----1031 1032func.func @get_consumer(%arg0: index, %arg1: index) {1033 %0 = arith.muli %arg0, %arg1 : index1034 // expected-remark @below {{found addi}}1035 arith.addi %0, %arg1 : index1036 return1037}1038 1039module attributes {transform.with_named_sequence} {1040 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {1041 %muli = transform.structured.match ops{["arith.muli"]} in %arg1 : (!transform.any_op) -> !transform.any_op1042 %addi = transform.get_consumers_of_result %muli[0] : (!transform.any_op) -> !transform.any_op1043 transform.debug.emit_remark_at %addi, "found addi" : !transform.any_op1044 transform.yield1045 }1046}1047 1048// -----1049 1050func.func @get_consumer_fail_1(%arg0: index, %arg1: index) {1051 %0 = arith.muli %arg0, %arg1 : index1052 %1 = arith.muli %arg0, %arg1 : index1053 return1054}1055 1056module attributes {transform.with_named_sequence} {1057 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {1058 %muli = transform.structured.match ops{["arith.muli"]} in %arg1 : (!transform.any_op) -> !transform.any_op1059 // expected-error @below {{handle must be mapped to exactly one payload op}}1060 %bbarg = transform.get_consumers_of_result %muli[0] : (!transform.any_op) -> !transform.any_op1061 transform.yield1062 }1063}1064 1065// -----1066 1067func.func @get_consumer_fail_2(%arg0: index, %arg1: index) {1068 %0 = arith.muli %arg0, %arg1 : index1069 return1070}1071 1072module attributes {transform.with_named_sequence} {1073 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {1074 %muli = transform.structured.match ops{["arith.muli"]} in %arg1 : (!transform.any_op) -> !transform.any_op1075 // expected-error @below {{result number overflow}}1076 %bbarg = transform.get_consumers_of_result %muli[1] : (!transform.any_op) -> !transform.any_op1077 transform.yield1078 }1079}1080 1081// -----1082 1083func.func @split_handle(%a: index, %b: index, %c: index) {1084 %0 = arith.muli %a, %b : index1085 %1 = arith.muli %a, %c : index1086 return1087}1088 1089module attributes {transform.with_named_sequence} {1090 transform.named_sequence @__transform_main(%fun: !transform.any_op) {1091 %muli = transform.structured.match ops{["arith.muli"]} in %fun : (!transform.any_op) -> !transform.any_op1092 %h:2 = transform.split_handle %muli : (!transform.any_op) -> (!transform.any_op, !transform.any_op)1093 %p = transform.num_associations %h#0 : (!transform.any_op) -> !transform.param<i64>1094 // expected-remark @below {{1}}1095 transform.debug.emit_param_as_remark %p : !transform.param<i64>1096 %muli_2 = transform.structured.match ops{["arith.muli"]} in %fun : (!transform.any_op) -> !transform.any_op1097 // expected-error @below {{expected to contain 3 payloads but it contains 2 payloads}}1098 %h_2:3 = transform.split_handle %muli_2 : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op)1099 transform.yield1100 }1101}1102 1103// -----1104 1105func.func @split_handle(%a: index, %b: index, %c: index) {1106 %0 = arith.muli %a, %b : index1107 %1 = arith.muli %a, %c : index1108 return1109}1110 1111module attributes {transform.with_named_sequence} {1112 transform.named_sequence @__transform_main(%root: !transform.any_op) {1113 transform.sequence %root : !transform.any_op failures(suppress) {1114 ^bb1(%fun: !transform.any_op):1115 %muli = transform.structured.match ops{["arith.muli"]} in %fun : (!transform.any_op) -> !transform.any_op1116 %h:2 = split_handle %muli : (!transform.any_op) -> (!transform.any_op, !transform.any_op)1117 %p = transform.num_associations %h#0 : (!transform.any_op) -> !transform.param<i64>1118 // expected-remark @below {{1}}1119 transform.debug.emit_param_as_remark %p : !transform.param<i64>1120 %muli_2 = transform.structured.match ops{["arith.muli"]} in %fun : (!transform.any_op) -> !transform.any_op1121 // Silenceable failure and all handles are now empty.1122 %h_2:3 = split_handle %muli_2 : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op)1123 %p2 = transform.num_associations %h_2#0 : (!transform.any_op) -> !transform.param<i64>1124 // expected-remark @below {{0}}1125 transform.debug.emit_param_as_remark %p2 : !transform.param<i64>1126 }1127 transform.yield1128 }1129}1130 1131// -----1132 1133func.func @split_handle(%a: index, %b: index, %c: index) {1134 %0 = arith.muli %a, %b : index1135 %1 = arith.muli %a, %c : index1136 return1137}1138 1139module attributes {transform.with_named_sequence} {1140 transform.named_sequence @__transform_main(%fun: !transform.any_op) {1141 %muli_2 = transform.structured.match ops{["arith.muli"]} in %fun : (!transform.any_op) -> !transform.any_op1142 // No error, last result handle is empty.1143 %h:3 = transform.split_handle %muli_2 {fail_on_payload_too_small = false} : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op)1144 %p = transform.num_associations %h#0 : (!transform.any_op) -> !transform.param<i64>1145 // expected-remark @below {{1}}1146 transform.debug.emit_param_as_remark %p : !transform.param<i64>1147 %p2 = transform.num_associations %h#1 : (!transform.any_op) -> !transform.param<i64>1148 // expected-remark @below {{1}}1149 transform.debug.emit_param_as_remark %p2 : !transform.param<i64>1150 %p3 = transform.num_associations %h#2 : (!transform.any_op) -> !transform.param<i64>1151 // expected-remark @below {{0}}1152 transform.debug.emit_param_as_remark %p3 : !transform.param<i64>1153 transform.yield1154 }1155}1156 1157// -----1158 1159func.func @split_handle(%a: index, %b: index, %c: index) {1160 %0 = arith.muli %a, %b : index1161 %1 = arith.muli %a, %c : index1162 %2 = arith.muli %a, %c : index1163 %3 = arith.muli %a, %c : index1164 return1165}1166 1167module attributes {transform.with_named_sequence} {1168 transform.named_sequence @__transform_main(%fun: !transform.any_op) {1169 %muli_2 = transform.structured.match ops{["arith.muli"]} in %fun : (!transform.any_op) -> !transform.any_op1170 %h:2 = transform.split_handle %muli_2 {overflow_result = 0} : (!transform.any_op) -> (!transform.any_op, !transform.any_op)1171 %p = transform.num_associations %h#0 : (!transform.any_op) -> !transform.param<i64>1172 // expected-remark @below {{3}}1173 transform.debug.emit_param_as_remark %p : !transform.param<i64>1174 %p2 = transform.num_associations %h#1 : (!transform.any_op) -> !transform.param<i64>1175 // expected-remark @below {{1}}1176 transform.debug.emit_param_as_remark %p2 : !transform.param<i64>1177 transform.yield1178 }1179}1180 1181// -----1182 1183func.func private @opaque() -> (i32, i32)1184 1185func.func @split_handle() {1186 func.call @opaque() : () -> (i32, i32)1187 return1188}1189 1190module attributes {transform.with_named_sequence} {1191 transform.named_sequence @__transform_main(%fun: !transform.any_op) {1192 %op = transform.structured.match ops{["func.call"]} in %fun : (!transform.any_op) -> !transform.any_op1193 %val = transform.get_result %op[all] : (!transform.any_op) -> !transform.any_value1194 %p = transform.num_associations %val : (!transform.any_value) -> !transform.any_param1195 // expected-remark @below {{total 2}}1196 transform.debug.emit_param_as_remark %p, "total" : !transform.any_param1197 %h:2 = transform.split_handle %val : (!transform.any_value) -> (!transform.any_value, !transform.any_value)1198 %p1 = transform.num_associations %h#0 : (!transform.any_value) -> !transform.any_param1199 %p2 = transform.num_associations %h#1 : (!transform.any_value) -> !transform.any_param1200 // expected-remark @below {{first 1}}1201 transform.debug.emit_param_as_remark %p1, "first" : !transform.any_param1202 // expected-remark @below {{second 1}}1203 transform.debug.emit_param_as_remark %p1, "second" : !transform.any_param1204 transform.yield1205 }1206}1207 1208// -----1209 1210func.func private @opaque() -> (i32, i32)1211 1212func.func @split_handle() {1213 func.call @opaque() : () -> (i32, i32)1214 return1215}1216 1217module attributes {transform.with_named_sequence} {1218 transform.named_sequence @__transform_main(%fun: !transform.any_op) {1219 %op = transform.structured.match ops{["func.call"]} in %fun : (!transform.any_op) -> !transform.any_op1220 %val = transform.get_result %op[all] : (!transform.any_op) -> !transform.any_value1221 %type = transform.get_type %val : (!transform.any_value) -> !transform.any_param1222 %p = transform.num_associations %type : (!transform.any_param) -> !transform.any_param1223 // expected-remark @below {{total 2}}1224 transform.debug.emit_param_as_remark %p, "total" : !transform.any_param1225 %h:2 = transform.split_handle %type : (!transform.any_param) -> (!transform.any_param, !transform.any_param)1226 %p1 = transform.num_associations %h#0 : (!transform.any_param) -> !transform.any_param1227 %p2 = transform.num_associations %h#1 : (!transform.any_param) -> !transform.any_param1228 // expected-remark @below {{first 1}}1229 transform.debug.emit_param_as_remark %p1, "first" : !transform.any_param1230 // expected-remark @below {{second 1}}1231 transform.debug.emit_param_as_remark %p1, "second" : !transform.any_param1232 transform.yield1233 }1234}1235 1236// -----1237 1238module attributes {transform.with_named_sequence} {1239 transform.named_sequence @__transform_main(%fun: !transform.any_op) {1240 // expected-error @below {{op expects result types to implement the same transform interface as the operand type}}1241 transform.split_handle %fun : (!transform.any_op) -> (!transform.any_op, !transform.any_value)1242 transform.yield1243 }1244}1245 1246// -----1247 1248"test.some_op"() : () -> ()1249"other_dialect.other_op"() : () -> ()1250 1251module attributes {transform.with_named_sequence} {1252 transform.named_sequence @__transform_main(%root: !transform.any_op) {1253 transform.with_pdl_patterns %root : !transform.any_op {1254 ^bb0(%arg0: !transform.any_op):1255 pdl.pattern @some : benefit(1) {1256 %0 = pdl.operation "test.some_op"1257 pdl.rewrite %0 with "transform.dialect"1258 }1259 1260 sequence %arg0 : !transform.any_op failures(propagate) {1261 ^bb1(%arg1: !transform.any_op):1262 %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op1263 %2 = transform.cast %0 : !transform.any_op to !transform.test_dialect_op1264 transform.cast %2 : !transform.test_dialect_op to !transform.any_op1265 }1266 }1267 transform.yield1268 }1269}1270 1271// -----1272 1273"test.some_op"() : () -> ()1274"other_dialect.other_op"() : () -> ()1275 1276module attributes {transform.with_named_sequence} {1277 transform.named_sequence @__transform_main(%root: !transform.any_op) {1278 transform.with_pdl_patterns %root : !transform.any_op {1279 ^bb0(%arg0: !transform.any_op):1280 pdl.pattern @other : benefit(1) {1281 %0 = pdl.operation "other_dialect.other_op"1282 pdl.rewrite %0 with "transform.dialect"1283 }1284 1285 sequence %arg0 : !transform.any_op failures(propagate) {1286 ^bb1(%arg1: !transform.any_op):1287 %0 = pdl_match @other in %arg1 : (!transform.any_op) -> !transform.any_op1288 // expected-error @below {{expected the payload operation to belong to the 'test' dialect}}1289 %2 = transform.cast %0 : !transform.any_op to !transform.test_dialect_op1290 transform.cast %2 : !transform.test_dialect_op to !transform.any_op1291 }1292 }1293 transform.yield1294 }1295}1296 1297// -----1298 1299"test.some_op"() : () -> ()1300"other_dialect.other_op"() : () -> ()1301 1302module attributes {transform.with_named_sequence} {1303 transform.named_sequence @__transform_main(%root: !transform.any_op) {1304 transform.with_pdl_patterns %root : !transform.any_op {1305 ^bb0(%arg0: !transform.any_op):1306 pdl.pattern @some : benefit(1) {1307 %0 = pdl.operation "test.some_op"1308 pdl.rewrite %0 with "transform.dialect"1309 }1310 1311 sequence %arg0 : !transform.any_op failures(propagate) {1312 ^bb1(%arg1: !transform.any_op):1313 %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op1314 %2 = transform.cast %0 : !transform.any_op to !transform.op<"test.some_op">1315 transform.cast %2 : !transform.op<"test.some_op"> to !transform.any_op1316 }1317 }1318 transform.yield1319 }1320}1321 1322// -----1323 1324"test.some_op"() : () -> ()1325// expected-note @below {{payload operation}}1326"other_dialect.other_op"() : () -> ()1327 1328module attributes {transform.with_named_sequence} {1329 transform.named_sequence @__transform_main(%root: !transform.any_op) {1330 transform.with_pdl_patterns %root : !transform.any_op {1331 ^bb0(%arg0: !transform.any_op):1332 pdl.pattern @other : benefit(1) {1333 %0 = pdl.operation "other_dialect.other_op"1334 pdl.rewrite %0 with "transform.dialect"1335 }1336 1337 sequence %arg0 : !transform.any_op failures(propagate) {1338 ^bb1(%arg1: !transform.any_op):1339 %0 = pdl_match @other in %arg1 : (!transform.any_op) -> !transform.any_op1340 // expected-error @below {{incompatible payload operation name}}1341 %2 = transform.cast %0 : !transform.any_op to !transform.op<"test.some_op">1342 transform.cast %2 : !transform.op<"test.some_op"> to !transform.any_op1343 }1344 }1345 transform.yield1346 }1347}1348 1349// -----1350 1351module attributes {transform.with_named_sequence} {1352 transform.named_sequence @__transform_main(%root: !transform.any_op) {1353 transform.with_pdl_patterns %root : !transform.any_op {1354 ^bb0(%arg0: !transform.any_op):1355 transform.sequence %arg0 : !transform.any_op failures(propagate) {1356 ^bb0(%arg1: !transform.any_op):1357 %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op1358 // here, the handles nested under are {%root, %arg0, %arg1, %0}1359 // expected-remark @below {{4 handles nested under}}1360 transform.test_report_number_of_tracked_handles_nested_under %arg1 : !transform.any_op1361 // expected-remark @below {{erased}}1362 transform.test_emit_remark_and_erase_operand %0, "erased" : !transform.any_op1363 // here, the handles nested under are only {%root, %arg0, %arg1}1364 // expected-remark @below {{3 handles nested under}}1365 transform.test_report_number_of_tracked_handles_nested_under %arg1 : !transform.any_op1366 }1367 1368 pdl.pattern @some : benefit(1) {1369 %0 = pdl.operation "test.some_op"1370 pdl.rewrite %0 with "transform.dialect"1371 }1372 }1373 transform.yield1374 }1375}1376 1377"test.some_op"() : () -> ()1378 1379// -----1380 1381func.func @split_handle(%a: index, %b: index, %c: index) {1382 %0 = arith.muli %a, %b : index1383 %1 = arith.muli %a, %c : index1384 return1385}1386 1387module attributes {transform.with_named_sequence} {1388 transform.named_sequence @__transform_main(%root: !transform.any_op) {1389 transform.sequence %root : !transform.any_op -> !transform.any_op failures(propagate) {1390 ^bb1(%fun: !transform.any_op):1391 %muli = transform.structured.match ops{["arith.muli"]} in %fun : (!transform.any_op) -> !transform.any_op1392 // expected-error @below {{expected to contain 3 payloads but it contains 2 payloads}}1393 %h_2:3 = split_handle %muli : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op)1394 /// Test that yield does not crash in the presence of silenceable error in1395 /// propagate mode.1396 yield %fun : !transform.any_op1397 }1398 transform.yield1399 }1400}1401 1402// -----1403 1404module attributes {transform.with_named_sequence} {1405 transform.named_sequence @__transform_main(%root: !transform.any_op) {1406 transform.sequence %root : !transform.any_op -> !transform.any_op failures(suppress) {1407 ^bb0(%arg0: !transform.any_op):1408 %muli = transform.structured.match ops{["arith.muli"]} in %arg0 : (!transform.any_op) -> !transform.any_op1409 // Edge case propagating empty handles in splitting.1410 %0:3 = split_handle %muli : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op)1411 // Test does not crash when accessing the empty handle.1412 yield %0#0 : !transform.any_op1413 }1414 transform.yield1415 }1416}1417 1418// -----1419 1420module attributes {transform.with_named_sequence} {1421 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1422 %0 = transform.test_produce_param (0 : i32) : !transform.test_dialect_param1423 // expected-remark @below {{0 : i32}}1424 transform.debug.emit_param_as_remark %0 : !transform.test_dialect_param1425 transform.yield1426 }1427}1428 1429// -----1430 1431module attributes {transform.with_named_sequence} {1432 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1433 // expected-error @below {{expected the type of the parameter attribute ('i32') to match the parameter type ('i64')}}1434 transform.test_produce_param (0 : i32) : !transform.param<i64>1435 transform.yield1436 }1437}1438 1439// -----1440 1441 1442module attributes {transform.with_named_sequence} {1443 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1444 %0 = transform.test_add_to_param 401445 %1 = transform.test_add_to_param %0, 21446 // expected-remark @below {{42 : i32}}1447 transform.debug.emit_param_as_remark %1 : !transform.test_dialect_param1448 transform.yield1449 }1450}1451 1452// -----1453 1454module attributes {transform.with_named_sequence} {1455 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1456 %0 = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op1457 %1 = transform.test_produce_param_with_number_of_test_ops %0 : !transform.any_op1458 // expected-remark @below {{1 : i32, 3 : i32}}1459 transform.debug.emit_param_as_remark %1 : !transform.test_dialect_param1460 %2 = transform.test_add_to_param %1, 1001461 // expected-remark @below {{101 : i32, 103 : i32}}1462 transform.debug.emit_param_as_remark %2 : !transform.test_dialect_param1463 transform.yield1464 }1465}1466 1467func.func private @one_test_op(%arg0: i32) {1468 "test.op_a"(%arg0) { attr = 0 : i32} : (i32) -> i321469 return1470}1471 1472func.func private @three_test_ops(%arg0: i32) {1473 "test.op_a"(%arg0) { attr = 0 : i32} : (i32) -> i321474 "test.op_a"(%arg0) { attr = 0 : i32} : (i32) -> i321475 "test.op_a"(%arg0) { attr = 0 : i32} : (i32) -> i321476 return1477}1478 1479// -----1480 1481// expected-note @below {{when applied to this op}}1482module attributes {transform.with_named_sequence} {1483 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1484 // expected-error @below {{expected to produce an Operation * for result #0}}1485 transform.test_produce_transform_param_or_forward_operand %arg01486 { first_result_is_param }1487 : (!transform.any_op) -> (!transform.any_op, !transform.param<i64>)1488 transform.yield1489 }1490}1491 1492// -----1493 1494// Should not fail.1495 1496module attributes {transform.with_named_sequence} {1497 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1498 transform.test_produce_transform_param_or_forward_operand %arg01499 { first_result_is_null }1500 : (!transform.any_op) -> (!transform.any_op, !transform.param<i64>)1501 transform.yield1502 }1503}1504 1505// -----1506 1507// expected-note @below {{when applied to this op}}1508module attributes {transform.with_named_sequence} {1509 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1510 // expected-error @below {{expected to produce an Attribute for result #1}}1511 transform.test_produce_transform_param_or_forward_operand %arg01512 { second_result_is_handle }1513 : (!transform.any_op) -> (!transform.any_op, !transform.param<i64>)1514 transform.yield1515 }1516}1517 1518// -----1519 1520// expected-note @below {{when applied to this op}}1521module attributes {transform.with_named_sequence} {1522 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1523 // expected-error @below {{expected to produce a Value for result #0}}1524 transform.test_produce_transform_param_or_forward_operand %arg01525 { second_result_is_handle }1526 : (!transform.any_op) -> (!transform.any_value, !transform.param<i64>)1527 transform.yield1528 }1529}1530 1531// -----1532 1533module attributes {transform.with_named_sequence} {1534 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1535 // expected-error @below {{attempting to assign a null payload op to this transform value}}1536 %0 = transform.test_produce_null_payload : !transform.any_op1537 transform.yield1538 }1539}1540 1541// -----1542 1543module attributes {transform.with_named_sequence} {1544 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1545 // expected-error @below {{attempting to assign a null parameter to this transform value}}1546 %0 = transform.test_produce_null_param : !transform.param<i64>1547 transform.yield1548 }1549}1550 1551// -----1552 1553module attributes {transform.with_named_sequence} {1554 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1555 // expected-error @below {{attempting to assign a null payload value to this transform handle}}1556 %0 = transform.test_produce_null_value : !transform.any_value1557 transform.yield1558 }1559}1560 1561// -----1562 1563// expected-error @below {{could not find a nested named sequence with name: __transform_main}}1564module {1565}1566 1567// -----1568 1569module attributes {transform.with_named_sequence} {1570 // expected-remark @below {{value handle}}1571 // expected-note @below {{value handle points to a block argument #0 in block #0 in region #0}}1572 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1573 %0 = transform.test_produce_value_handle_to_self_operand %arg0 : (!transform.any_op) -> !transform.any_value1574 transform.debug.emit_remark_at %0, "value handle" : !transform.any_value1575 transform.yield1576 }1577}1578 1579// -----1580 1581// expected-remark @below {{result handle}}1582// expected-note @below {{value handle points to an op result #1}}1583%0:2 = "test.get_two_results"() : () -> (i32, i32)1584// expected-remark @below {{result handle}}1585// expected-note @below {{value handle points to an op result #1}}1586%1:3 = "test.get_three_results"() : () -> (i32, i32, f32)1587 1588module attributes {transform.with_named_sequence} {1589 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1590 %2 = transform.structured.match ops{["test.get_two_results", "test.get_three_results"]} in %arg0 : (!transform.any_op) -> !transform.any_op1591 %3 = transform.test_produce_value_handle_to_result %2, 1 : (!transform.any_op) -> !transform.any_value1592 transform.debug.emit_remark_at %3, "result handle" : !transform.any_value1593 transform.yield1594 }1595}1596 1597// -----1598 1599"test.op_with_regions"() ({1600^bb0:1601 "test.regon_terminator"() : () -> ()1602}, {1603^bb1:1604 "test.regon_terminator"() : () -> ()1605// expected-remark @below {{block argument handle}}1606// expected-note @below {{value handle points to a block argument #2 in block #1 in region #1}}1607^bb2(%arg0: i32, %arg1: f64, %arg3: index):1608 "test.match_anchor"() : () -> ()1609 "test.regon_terminator"() : () -> ()1610}) : () -> ()1611 1612module attributes {transform.with_named_sequence} {1613 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1614 %2 = transform.structured.match ops{["test.match_anchor"]} in %arg0 : (!transform.any_op) -> !transform.any_op1615 %3 = transform.test_produce_value_handle_to_argument_of_parent_block %2, 2 : (!transform.any_op) -> !transform.any_value1616 transform.debug.emit_remark_at %3, "block argument handle" : !transform.any_value1617 transform.yield1618 }1619}1620 1621// -----1622 1623module attributes {transform.with_named_sequence} {1624 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1625 // expected-note @below {{value defined here with type '!transform.test_dialect_param'}}1626 %0 = transform.test_produce_param_with_number_of_test_ops %arg0 : !transform.any_op1627 // expected-error @below {{unexpectedly consumed a value that is not a handle as operand #0}}1628 transform.test_consume_operand %0 : !transform.test_dialect_param1629 transform.yield1630 }1631}1632 1633// -----1634 1635// expected-remark @below {{addi operand}}1636// expected-note @below {{value handle points to a block argument #0}}1637func.func @get_operand_of_op(%arg0: index, %arg1: index) -> index {1638 %r = arith.addi %arg0, %arg1 : index1639 return %r : index1640}1641 1642module attributes {transform.with_named_sequence} {1643 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {1644 %addi = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op1645 %operand = transform.get_operand %addi[0] : (!transform.any_op) -> !transform.any_value1646 transform.debug.emit_remark_at %operand, "addi operand" : !transform.any_value1647 transform.yield1648 }1649}1650 1651// -----1652 1653func.func @get_out_of_bounds_operand_of_op(%arg0: index, %arg1: index) -> index {1654 // expected-note @below {{while considering positions of this payload operation}}1655 %r = arith.addi %arg0, %arg1 : index1656 return %r : index1657}1658 1659module attributes {transform.with_named_sequence} {1660 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {1661 %addi = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op1662 // expected-error @below {{position overflow 2 (updated from 2) for maximum 2}}1663 %operand = transform.get_operand %addi[2] : (!transform.any_op) -> !transform.any_value1664 transform.debug.emit_remark_at %operand, "addi operand" : !transform.any_value1665 transform.yield1666 }1667}1668 1669// -----1670 1671// expected-remark @below {{addi operand}}1672// expected-note @below {{value handle points to a block argument #1}}1673func.func @get_inverted_operand_of_op(%arg0: index, %arg1: index) -> index {1674 %r = arith.addi %arg0, %arg1 : index1675 return %r : index1676}1677 1678module attributes {transform.with_named_sequence} {1679 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {1680 %addi = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op1681 %operand = transform.get_operand %addi[except(0)] : (!transform.any_op) -> !transform.any_value1682 transform.debug.emit_remark_at %operand, "addi operand" : !transform.any_value1683 transform.yield1684 }1685}1686 1687// -----1688 1689func.func @get_multiple_operands_of_op(%arg0: index, %arg1: index) -> index {1690 %r = arith.addi %arg0, %arg1 : index1691 return %r : index1692}1693 1694module attributes {transform.with_named_sequence} {1695 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {1696 %addui = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op1697 %operands = transform.get_operand %addui[all] : (!transform.any_op) -> !transform.any_value1698 %p = transform.num_associations %operands : (!transform.any_value) -> !transform.param<i64>1699 // expected-remark @below {{2}}1700 transform.debug.emit_param_as_remark %p : !transform.param<i64>1701 transform.yield1702 }1703}1704 1705// -----1706 1707func.func @get_result_of_op(%arg0: index, %arg1: index) -> index {1708 // expected-remark @below {{addi result}}1709 // expected-note @below {{value handle points to an op result #0}}1710 %r = arith.addi %arg0, %arg1 : index1711 return %r : index1712}1713 1714module attributes {transform.with_named_sequence} {1715 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {1716 %addi = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op1717 %result = transform.get_result %addi[0] : (!transform.any_op) -> !transform.any_value1718 transform.debug.emit_remark_at %result, "addi result" : !transform.any_value1719 transform.yield1720 }1721}1722 1723// -----1724 1725func.func @get_out_of_bounds_result_of_op(%arg0: index, %arg1: index) -> index {1726 // expected-note @below {{while considering positions of this payload operation}}1727 %r = arith.addi %arg0, %arg1 : index1728 return %r : index1729}1730 1731module attributes {transform.with_named_sequence} {1732 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {1733 %addi = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op1734 // expected-error @below {{position overflow 1 (updated from 1) for maximum 1}}1735 %result = transform.get_result %addi[1] : (!transform.any_op) -> !transform.any_value1736 transform.debug.emit_remark_at %result, "addi result" : !transform.any_value1737 transform.yield1738 }1739}1740 1741// -----1742 1743func.func @get_result_of_op(%arg0: index, %arg1: index) -> index {1744 // expected-remark @below {{matched}}1745 %r = arith.addi %arg0, %arg1 : index1746 return %r : index1747}1748 1749module attributes {transform.with_named_sequence} {1750 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {1751 %addi = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op1752 %result = transform.get_result %addi[0] : (!transform.any_op) -> !transform.any_value1753 %op = transform.get_defining_op %result : (!transform.any_value) -> !transform.any_op1754 transform.debug.emit_remark_at %op, "matched" : !transform.any_op1755 transform.yield1756 }1757}1758 1759// -----1760 1761func.func @get_multiple_result_of_op(%arg0: index, %arg1: index) -> (index, i1) {1762 %r, %b = arith.addui_extended %arg0, %arg1 : index, i11763 return %r, %b : index, i11764}1765 1766module attributes {transform.with_named_sequence} {1767 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {1768 %addui = transform.structured.match ops{["arith.addui_extended"]} in %arg1 : (!transform.any_op) -> !transform.any_op1769 %results = transform.get_result %addui[all] : (!transform.any_op) -> !transform.any_value1770 %p = transform.num_associations %results : (!transform.any_value) -> !transform.param<i64>1771 // expected-remark @below {{2}}1772 transform.debug.emit_param_as_remark %p : !transform.param<i64>1773 transform.yield1774 }1775}1776 1777// -----1778 1779// expected-note @below {{target value}}1780func.func @get_result_of_op_bbarg(%arg0: index, %arg1: index) -> index {1781 %r = arith.addi %arg0, %arg1 : index1782 return %r : index1783}1784 1785module attributes {transform.with_named_sequence} {1786 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {1787 %addi = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op1788 %bbarg = transform.test_produce_value_handle_to_argument_of_parent_block %addi, 0 : (!transform.any_op) -> !transform.any_value1789 // expected-error @below {{cannot get defining op of block argument}}1790 %op = transform.get_defining_op %bbarg : (!transform.any_value) -> !transform.any_op1791 transform.debug.emit_remark_at %op, "matched" : !transform.any_op1792 transform.yield1793 }1794}1795 1796// -----1797 1798module @named_inclusion attributes { transform.with_named_sequence } {1799 1800 transform.named_sequence @foo(%arg0: !transform.any_op {transform.readonly}) -> () {1801 // expected-remark @below {{applying transformation "a"}}1802 transform.test_transform_op "a"1803 transform.yield1804 }1805 1806 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1807 transform.include @foo failures(propagate) (%arg0) : (!transform.any_op) -> ()1808 transform.yield1809 }1810}1811 1812// -----1813 1814module @named_inclusion_in_named attributes { transform.with_named_sequence } {1815 1816 transform.named_sequence @foo(%arg0: !transform.any_op {transform.readonly}) -> () {1817 // expected-remark @below {{applying transformation "a"}}1818 transform.test_transform_op "a"1819 transform.yield1820 }1821 1822 transform.named_sequence @bar(%arg0: !transform.any_op {transform.readonly}) -> () {1823 // expected-remark @below {{applying transformation "b"}}1824 transform.test_transform_op "b"1825 transform.include @foo failures(propagate) (%arg0) : (!transform.any_op) -> ()1826 transform.yield1827 }1828 1829 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1830 transform.include @bar failures(suppress) (%arg0) : (!transform.any_op) -> ()1831 transform.yield1832 }1833}1834 1835// -----1836 1837// expected-remark @below {{operation}}1838module @named_operands attributes { transform.with_named_sequence } {1839 1840 transform.named_sequence @foo(%arg0: !transform.any_op {transform.readonly},1841 %arg1: !transform.any_value {transform.readonly}) -> () {1842 transform.debug.emit_remark_at %arg0, "operation" : !transform.any_op1843 transform.debug.emit_remark_at %arg1, "value" : !transform.any_value1844 transform.yield1845 }1846 1847 // expected-remark @below {{value}}1848 // expected-note @below {{value handle points to a block argument #0 in block #0 in region #0}}1849 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1850 %0 = transform.test_produce_value_handle_to_self_operand %arg0 : (!transform.any_op) -> !transform.any_value1851 transform.include @foo failures(propagate) (%arg0, %0) : (!transform.any_op, !transform.any_value) -> ()1852 transform.yield1853 }1854}1855 1856// -----1857 1858// expected-remark @below {{operation}}1859module @named_return attributes { transform.with_named_sequence } {1860 1861 // expected-remark @below {{value}}1862 // expected-note @below {{value handle points to a block argument #0 in block #0 in region #0}}1863 transform.named_sequence @foo(%arg0: !transform.any_op {transform.readonly}) -> (!transform.any_op, !transform.any_value) {1864 %0 = transform.test_produce_value_handle_to_self_operand %arg0 : (!transform.any_op) -> !transform.any_value1865 transform.yield %arg0, %0 : !transform.any_op, !transform.any_value1866 }1867 1868 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1869 %0:2 = transform.include @foo failures(propagate) (%arg0) : (!transform.any_op) -> (!transform.any_op, !transform.any_value)1870 transform.debug.emit_remark_at %0#0, "operation" : !transform.any_op1871 transform.debug.emit_remark_at %0#1, "value" : !transform.any_value1872 transform.yield1873 }1874}1875 1876// -----1877 1878module attributes { transform.with_named_sequence } {1879 transform.named_sequence @match1(%current: !transform.any_op {transform.readonly}) -> (!transform.any_op) {1880 transform.test_succeed_if_operand_of_op_kind %current, "test.some_op" : !transform.any_op1881 transform.yield %current : !transform.any_op1882 }1883 1884 transform.named_sequence @match2(%current: !transform.any_op {transform.readonly}) -> (!transform.any_op) {1885 transform.test_succeed_if_operand_of_op_kind %current, "func.func" : !transform.any_op1886 transform.yield %current : !transform.any_op1887 }1888 1889 transform.named_sequence @action1(%current: !transform.any_op {transform.readonly}) {1890 transform.debug.emit_remark_at %current, "matched1" : !transform.any_op1891 transform.yield1892 }1893 transform.named_sequence @action2(%current: !transform.any_op {transform.readonly}) {1894 transform.debug.emit_remark_at %current, "matched2" : !transform.any_op1895 transform.yield1896 }1897 1898 transform.named_sequence @__transform_main(%root: !transform.any_op) {1899 transform.foreach_match in %root1900 @match1 -> @action1,1901 @match2 -> @action21902 : (!transform.any_op) -> (!transform.any_op)1903 transform.yield1904 }1905 1906 // expected-remark @below {{matched2}}1907 func.func private @foo()1908 // expected-remark @below {{matched2}}1909 func.func private @bar()1910 "test.testtest"() : () -> ()1911 // expected-remark @below {{matched1}}1912 "test.some_op"() : () -> ()1913}1914 1915// -----1916 1917module attributes { transform.with_named_sequence } {1918 transform.named_sequence @match(!transform.any_op {transform.readonly})1919 transform.named_sequence @action()1920 1921 transform.named_sequence @__transform_main(%root: !transform.any_op) {1922 // expected-error @below {{unresolved external symbol @match}}1923 transform.foreach_match in %root1924 @match -> @action : (!transform.any_op) -> !transform.any_op1925 transform.yield1926 }1927}1928 1929// -----1930 1931module attributes { transform.with_named_sequence } {1932 transform.named_sequence @match(%arg: !transform.any_op {transform.readonly}) {1933 transform.yield1934 }1935 transform.named_sequence @action()1936 1937 transform.named_sequence @__transform_main(%root: !transform.any_op) {1938 // expected-error @below {{unresolved external symbol @action}}1939 transform.foreach_match in %root1940 @match -> @action : (!transform.any_op) -> !transform.any_op1941 transform.yield1942 }1943}1944 1945// -----1946 1947module attributes { transform.with_named_sequence } {1948 transform.named_sequence @match(%arg: !transform.any_op {transform.readonly}) {1949 // expected-error @below {{expected operations in the match part to implement MatchOpInterface}}1950 "test.unknown_op"() : () -> ()1951 transform.yield1952 }1953 transform.named_sequence @action() {1954 transform.yield1955 }1956 1957 transform.named_sequence @__transform_main(%root: !transform.any_op) {1958 transform.foreach_match in %root1959 @match -> @action : (!transform.any_op) -> !transform.any_op1960 transform.yield1961 }1962}1963 1964// -----1965 1966module attributes { transform.with_named_sequence } {1967 transform.named_sequence @match_func(%arg0: !transform.any_op {transform.readonly})1968 -> !transform.any_op {1969 transform.match.operation_name %arg0 ["func.func"] : !transform.any_op1970 transform.yield %arg0 : !transform.any_op1971 }1972 1973 transform.named_sequence @print_func(%arg0: !transform.any_op {transform.readonly}) {1974 transform.debug.emit_remark_at %arg0, "matched func" : !transform.any_op1975 transform.yield1976 }1977 1978 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {1979 transform.foreach_match in %arg0 @match_func -> @print_func : (!transform.any_op) -> !transform.any_op1980 transform.yield1981 }1982 1983 // expected-remark @below {{matched func}}1984 func.func @payload() {1985 return1986 }1987 1988 // expected-remark @below {{matched func}}1989 func.func private @declaration()1990 1991 "test.something_else"() : () -> ()1992}1993 1994// -----1995 1996module attributes { transform.with_named_sequence } {1997 transform.named_sequence @eq_1(%arg0: !transform.any_op {transform.readonly})1998 -> !transform.any_op {1999 transform.match.operation_name %arg0 ["func.func"] : !transform.any_op2000 %0 = transform.test_produce_param_with_number_of_test_ops %arg0 : !transform.any_op2001 %1 = transform.param.constant 1 : i32 -> !transform.test_dialect_param2002 transform.match.param.cmpi eq %0, %1 : !transform.test_dialect_param2003 transform.debug.emit_remark_at %arg0, "matched == 1" : !transform.any_op2004 transform.yield %arg0 : !transform.any_op2005 }2006 2007 transform.named_sequence @ne_0(%arg0: !transform.any_op {transform.readonly})2008 -> !transform.any_op {2009 transform.match.operation_name %arg0 ["func.func"] : !transform.any_op2010 %0 = transform.test_produce_param_with_number_of_test_ops %arg0 : !transform.any_op2011 %1 = transform.param.constant 0 : i32 -> !transform.test_dialect_param2012 transform.match.param.cmpi ne %0, %1 : !transform.test_dialect_param2013 transform.debug.emit_remark_at %arg0, "matched != 0" : !transform.any_op2014 transform.yield %arg0 : !transform.any_op2015 }2016 2017 transform.named_sequence @gt_m1(%arg0: !transform.any_op {transform.readonly})2018 -> !transform.any_op {2019 transform.match.operation_name %arg0 ["func.func"] : !transform.any_op2020 %0 = transform.test_produce_param_with_number_of_test_ops %arg0 : !transform.any_op2021 %1 = transform.param.constant -1 : i32 -> !transform.test_dialect_param2022 transform.match.param.cmpi gt %0, %1 : !transform.test_dialect_param2023 transform.debug.emit_remark_at %arg0, "matched > -1" : !transform.any_op2024 transform.yield %arg0 : !transform.any_op2025 }2026 2027 transform.named_sequence @ge_1(%arg0: !transform.any_op {transform.readonly})2028 -> !transform.any_op {2029 transform.match.operation_name %arg0 ["func.func"] : !transform.any_op2030 %0 = transform.test_produce_param_with_number_of_test_ops %arg0 : !transform.any_op2031 %1 = transform.param.constant 1 : i32 -> !transform.test_dialect_param2032 transform.match.param.cmpi ge %0, %1 : !transform.test_dialect_param2033 transform.debug.emit_remark_at %arg0, "matched >= 1" : !transform.any_op2034 transform.yield %arg0 : !transform.any_op2035 }2036 2037 transform.named_sequence @lt_1(%arg0: !transform.any_op {transform.readonly})2038 -> !transform.any_op {2039 transform.match.operation_name %arg0 ["func.func"] : !transform.any_op2040 %0 = transform.test_produce_param_with_number_of_test_ops %arg0 : !transform.any_op2041 %1 = transform.param.constant 1 : i32 -> !transform.test_dialect_param2042 transform.match.param.cmpi lt %0, %1 : !transform.test_dialect_param2043 transform.debug.emit_remark_at %arg0, "matched < 1" : !transform.any_op2044 transform.yield %arg0 : !transform.any_op2045 }2046 2047 transform.named_sequence @le_1(%arg0: !transform.any_op {transform.readonly})2048 -> !transform.any_op {2049 transform.match.operation_name %arg0 ["func.func"] : !transform.any_op2050 %0 = transform.test_produce_param_with_number_of_test_ops %arg0 : !transform.any_op2051 %1 = transform.param.constant 1 : i32 -> !transform.test_dialect_param2052 transform.match.param.cmpi le %0, %1 : !transform.test_dialect_param2053 transform.debug.emit_remark_at %arg0, "matched <= 1" : !transform.any_op2054 transform.yield %arg0 : !transform.any_op2055 }2056 2057 transform.named_sequence @do_nothing(%arg0: !transform.any_op {transform.readonly}) {2058 transform.yield2059 }2060 2061 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2062 %0 = transform.foreach_match in %arg0 @eq_1 -> @do_nothing : (!transform.any_op) -> !transform.any_op2063 %1 = transform.foreach_match in %0 @ne_0 -> @do_nothing : (!transform.any_op) -> !transform.any_op2064 %2 = transform.foreach_match in %1 @gt_m1 -> @do_nothing : (!transform.any_op) -> !transform.any_op2065 %3 = transform.foreach_match in %2 @ge_1 -> @do_nothing : (!transform.any_op) -> !transform.any_op2066 %4 = transform.foreach_match in %3 @lt_1 -> @do_nothing : (!transform.any_op) -> !transform.any_op2067 %5 = transform.foreach_match in %4 @le_1 -> @do_nothing : (!transform.any_op) -> !transform.any_op2068 transform.yield2069 }2070 2071 // expected-remark @below {{matched > -1}}2072 // expected-remark @below {{matched < 1}}2073 // expected-remark @below {{matched <= 1}}2074 func.func private @declaration()2075 2076 // expected-remark @below {{matched == 1}}2077 // expected-remark @below {{matched != 0}}2078 // expected-remark @below {{matched > -1}}2079 // expected-remark @below {{matched >= 1}}2080 // expected-remark @below {{matched <= 1}}2081 func.func @definition() {2082 "test.something"() : () -> ()2083 return2084 }2085}2086 2087// -----2088 2089// CHECK-LABEL: func @test_tracked_rewrite() {2090// CHECK-NEXT: transform.test_dummy_payload_op {new_op} : () -> i12091// CHECK-NEXT: transform.test_dummy_payload_op {new_op} : () -> i12092// CHECK-NEXT: return2093// CHECK-NEXT: }2094func.func @test_tracked_rewrite() {2095 %0 = transform.test_dummy_payload_op {replace_me} : () -> (i1)2096 %1 = transform.test_dummy_payload_op {erase_me} : () -> (i1)2097 %2 = transform.test_dummy_payload_op {replace_me} : () -> (i1)2098 func.return2099}2100 2101module attributes {transform.with_named_sequence} {2102 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {2103 %0 = transform.structured.match ops{["transform.test_dummy_payload_op"]} in %arg1 : (!transform.any_op) -> !transform.any_op2104 // expected-remark @below {{2 iterations}}2105 transform.test_tracked_rewrite %0 : (!transform.any_op) -> ()2106 // One replacement op (test.drop_mapping) is dropped from the mapping.2107 %p = transform.num_associations %0 : (!transform.any_op) -> !transform.param<i64>2108 // expected-remark @below {{2}}2109 transform.debug.emit_param_as_remark %p : !transform.param<i64>2110 transform.yield2111 }2112}2113 2114// -----2115 2116// Parameter deduplication happens by value2117 2118module attributes {transform.with_named_sequence} {2119 2120 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2121 %1 = transform.param.constant 1 -> !transform.param<i64>2122 %2 = transform.param.constant 1 -> !transform.param<i64>2123 %3 = transform.param.constant 2 -> !transform.param<i64>2124 %4 = transform.merge_handles %1, %2 { deduplicate } : !transform.param<i64>2125 %p = transform.num_associations %4 : (!transform.param<i64>) -> !transform.param<i64>2126 // expected-remark @below {{1}}2127 transform.debug.emit_param_as_remark %p : !transform.param<i64>2128 2129 %5 = transform.merge_handles %1, %1 { deduplicate } : !transform.param<i64>2130 %p2 = transform.num_associations %5 : (!transform.param<i64>) -> !transform.param<i64>2131 // expected-remark @below {{1}}2132 transform.debug.emit_param_as_remark %p2 : !transform.param<i64>2133 2134 %6 = transform.merge_handles %1, %3 { deduplicate } : !transform.param<i64>2135 %p3 = transform.num_associations %6 : (!transform.param<i64>) -> !transform.param<i64>2136 // expected-remark @below {{2}}2137 transform.debug.emit_param_as_remark %p3 : !transform.param<i64>2138 2139 %7 = transform.merge_handles %1, %1, %2, %3 : !transform.param<i64>2140 %p4 = transform.num_associations %7 : (!transform.param<i64>) -> !transform.param<i64>2141 // expected-remark @below {{4}}2142 transform.debug.emit_param_as_remark %p4 : !transform.param<i64>2143 transform.yield2144 }2145}2146 2147// -----2148 2149%0:3 = "test.get_two_results"() : () -> (i32, i32, f32)2150 2151module attributes {transform.with_named_sequence} {2152 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2153 %1 = transform.structured.match ops{["test.get_two_results"]} in %arg0 : (!transform.any_op) -> !transform.any_op2154 %2 = transform.test_produce_value_handle_to_result %1, 0 : (!transform.any_op) -> !transform.any_value2155 %3 = transform.test_produce_value_handle_to_result %1, 1 : (!transform.any_op) -> !transform.any_value2156 2157 %4 = transform.merge_handles %2, %2 { deduplicate } : !transform.any_value2158 %p = transform.num_associations %4 : (!transform.any_value) -> !transform.param<i64>2159 // expected-remark @below {{1}}2160 transform.debug.emit_param_as_remark %p : !transform.param<i64>2161 2162 %5 = transform.merge_handles %2, %3 { deduplicate } : !transform.any_value2163 %p2 = transform.num_associations %5 : (!transform.any_value) -> !transform.param<i64>2164 // expected-remark @below {{2}}2165 transform.debug.emit_param_as_remark %p2 : !transform.param<i64>2166 2167 %6 = transform.test_produce_value_handle_to_result %1, 0 : (!transform.any_op) -> !transform.any_value2168 %7 = transform.merge_handles %2, %6 { deduplicate } : !transform.any_value2169 %p3 = transform.num_associations %6 : (!transform.any_value) -> !transform.param<i64>2170 // expected-remark @below {{1}}2171 transform.debug.emit_param_as_remark %p3 : !transform.param<i64>2172 2173 %8 = transform.merge_handles %2, %2, %3, %4 : !transform.any_value2174 %p4 = transform.num_associations %8 : (!transform.any_value) -> !transform.param<i64>2175 // expected-remark @below {{4}}2176 transform.debug.emit_param_as_remark %p4 : !transform.param<i64>2177 transform.yield2178 }2179}2180// -----2181 2182// CHECK-LABEL: func @test_annotation()2183// CHECK-NEXT: "test.annotate_me"()2184// CHECK-SAME: any_attr = "example"2185// CHECK-SAME: broadcast_attr = 2 : i642186// CHECK-SAME: new_attr = 1 : i322187// CHECK-SAME: unit_attr2188// CHECK-NEXT: "test.annotate_me"()2189// CHECK-SAME: any_attr = "example"2190// CHECK-SAME: broadcast_attr = 2 : i642191// CHECK-SAME: existing_attr = "test"2192// CHECK-SAME: new_attr = 1 : i322193// CHECK-SAME: unit_attr2194// CHECK-NEXT: "test.annotate_me"()2195// CHECK-SAME: any_attr = "example"2196// CHECK-SAME: broadcast_attr = 2 : i642197// CHECK-SAME: new_attr = 1 : i322198// CHECK-SAME: unit_attr2199func.func @test_annotation() {2200 %0 = "test.annotate_me"() : () -> (i1)2201 %1 = "test.annotate_me"() {existing_attr = "test"} : () -> (i1)2202 %2 = "test.annotate_me"() {new_attr = 0} : () -> (i1)2203}2204 2205module attributes {transform.with_named_sequence} {2206 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2207 %0 = transform.structured.match ops{["test.annotate_me"]} in %arg0 : (!transform.any_op) -> !transform.any_op2208 %1 = transform.test_produce_param_with_number_of_test_ops %0 : !transform.any_op2209 transform.annotate %0 "new_attr" = %1 : !transform.any_op, !transform.test_dialect_param2210 2211 %2 = transform.param.constant 2 -> !transform.param<i64>2212 transform.annotate %0 "broadcast_attr" = %2 : !transform.any_op, !transform.param<i64>2213 transform.annotate %0 "unit_attr" : !transform.any_op2214 2215 %3 = transform.param.constant "example" -> !transform.any_param2216 transform.annotate %0 "any_attr" = %3 : !transform.any_op, !transform.any_param2217 transform.yield2218 }2219}2220 2221// -----2222 2223func.func @notify_payload_op_replaced(%arg0: index, %arg1: index) {2224 %0 = arith.muli %arg0, %arg1 {original} : index2225 // expected-remark @below{{updated handle}}2226 %1 = arith.muli %arg0, %arg1 {replacement} : index2227 return2228}2229 2230module attributes {transform.with_named_sequence} {2231 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {2232 %0 = transform.structured.match attributes{original} in %arg1 : (!transform.any_op) -> !transform.any_op2233 %1 = transform.structured.match attributes{replacement} in %arg1 : (!transform.any_op) -> !transform.any_op2234 transform.test_notify_payload_op_replaced %0, %1 : (!transform.any_op, !transform.any_op) -> ()2235 transform.debug.emit_remark_at %0, "updated handle" : !transform.any_op2236 transform.yield2237 }2238}2239 2240// -----2241 2242// CHECK-LABEL: func @test_apply_cse()2243// CHECK: %[[const:.*]] = arith.constant 0 : index2244// CHECK: %[[ex1:.*]] = scf.execute_region -> index {2245// CHECK: scf.yield %[[const]]2246// CHECK: }2247// CHECK: %[[ex2:.*]] = scf.execute_region -> index {2248// CHECK: scf.yield %[[const]]2249// CHECK: }2250// CHECK: return %[[const]], %[[ex1]], %[[ex2]]2251func.func @test_apply_cse() -> (index, index, index) {2252 // expected-remark @below{{eliminated 1}}2253 // expected-remark @below{{eliminated 2}}2254 %0 = arith.constant 0 : index2255 %1 = scf.execute_region -> index {2256 %2 = arith.constant 0 : index2257 scf.yield %2 : index2258 } {first}2259 %3 = scf.execute_region -> index {2260 %4 = arith.constant 0 : index2261 scf.yield %4 : index2262 } {second}2263 return %0, %1, %3 : index, index, index2264}2265 2266module attributes {transform.with_named_sequence} {2267 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {2268 %0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op2269 %first = transform.structured.match attributes{first} in %0 : (!transform.any_op) -> !transform.any_op2270 %elim_first = transform.structured.match ops{["arith.constant"]} in %first : (!transform.any_op) -> !transform.any_op2271 %second = transform.structured.match attributes{first} in %0 : (!transform.any_op) -> !transform.any_op2272 %elim_second = transform.structured.match ops{["arith.constant"]} in %first : (!transform.any_op) -> !transform.any_op2273 2274 // There are 3 arith.constant ops.2275 %all = transform.structured.match ops{["arith.constant"]} in %0 : (!transform.any_op) -> !transform.any_op2276 %p = transform.num_associations %all : (!transform.any_op) -> !transform.param<i64>2277 // expected-remark @below{{3}}2278 transform.debug.emit_param_as_remark %p : !transform.param<i64>2279 // "deduplicate" has no effect because these are 3 different ops.2280 %merged_before = transform.merge_handles deduplicate %all : !transform.any_op2281 %p2 = transform.num_associations %merged_before : (!transform.any_op) -> !transform.param<i64>2282 // expected-remark @below{{3}}2283 transform.debug.emit_param_as_remark %p2 : !transform.param<i64>2284 2285 // Apply CSE.2286 transform.apply_cse to %0 : !transform.any_op2287 2288 // The handle is still mapped to 3 arith.constant ops.2289 %p3 = transform.num_associations %all : (!transform.any_op) -> !transform.param<i64>2290 // expected-remark @below{{3}}2291 transform.debug.emit_param_as_remark %p3 : !transform.param<i64>2292 // But they are all the same op.2293 %merged_after = transform.merge_handles deduplicate %all : !transform.any_op2294 %p4 = transform.num_associations %merged_after : (!transform.any_op) -> !transform.param<i64>2295 // expected-remark @below{{1}}2296 transform.debug.emit_param_as_remark %p4 : !transform.param<i64>2297 2298 // The other handles were also updated.2299 transform.debug.emit_remark_at %elim_first, "eliminated 1" : !transform.any_op2300 %p5 = transform.num_associations %elim_first : (!transform.any_op) -> !transform.param<i64>2301 // expected-remark @below{{1}}2302 transform.debug.emit_param_as_remark %p5 : !transform.param<i64>2303 transform.debug.emit_remark_at %elim_second, "eliminated 2" : !transform.any_op2304 %p6 = transform.num_associations %elim_second : (!transform.any_op) -> !transform.param<i64>2305 // expected-remark @below{{1}}2306 transform.debug.emit_param_as_remark %p6 : !transform.param<i64>2307 transform.yield2308 }2309}2310 2311// -----2312 2313// CHECK-LABEL: func @test_licm(2314// CHECK: arith.muli2315// CHECK: scf.for {{.*}} {2316// CHECK: vector.print2317// CHECK: }2318func.func @test_licm(%arg0: index, %arg1: index, %arg2: index) {2319 scf.for %iv = %arg0 to %arg1 step %arg2 {2320 %0 = arith.muli %arg0, %arg1 : index2321 vector.print %0 : index2322 }2323 return2324}2325 2326module attributes {transform.with_named_sequence} {2327 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {2328 %0 = transform.structured.match ops{["scf.for"]} in %arg1 : (!transform.any_op) -> !transform.any_op2329 transform.apply_licm to %0 : !transform.any_op2330 transform.yield2331 }2332}2333 2334// -----2335 2336// expected-note @below{{when applied to this op}}2337module attributes {transform.with_named_sequence} {2338 func.func @test_licm_invalid() {2339 return2340 }2341 2342 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {2343 // expected-error @below{{transform applied to the wrong op kind}}2344 transform.apply_licm to %arg1 : !transform.any_op2345 transform.yield2346 }2347}2348 2349// -----2350 2351func.func @get_parent_op() {2352 // expected-remark @below{{found test.foo parent}}2353 "test.foo"() ({2354 // expected-remark @below{{direct parent}}2355 "test.bar"() ({2356 "test.qux"() : () -> ()2357 "test.qux"() : () -> ()2358 }) : () -> ()2359 }) : () -> ()2360}2361 2362module attributes {transform.with_named_sequence} {2363 transform.named_sequence @__transform_main(%arg1: !transform.any_op) {2364 %0 = transform.structured.match ops{["test.qux"]} in %arg1 : (!transform.any_op) -> !transform.any_op2365 2366 // Get parent by name.2367 %1 = transform.get_parent_op %0 {op_name = "test.foo"} : (!transform.any_op) -> !transform.any_op2368 transform.debug.emit_remark_at %1, "found test.foo parent" : !transform.any_op2369 2370 // Get immediate parent.2371 %2 = transform.get_parent_op %0 : (!transform.any_op) -> !transform.any_op2372 transform.debug.emit_remark_at %2, "direct parent" : !transform.any_op2373 %p = transform.num_associations %2 : (!transform.any_op) -> !transform.param<i64>2374 // expected-remark @below{{2}}2375 transform.debug.emit_param_as_remark %p : !transform.param<i64>2376 2377 // Deduplicate results.2378 %3 = transform.structured.match ops{["test.qux"]} in %arg1 : (!transform.any_op) -> !transform.any_op2379 %4 = transform.get_parent_op %3 {deduplicate} : (!transform.any_op) -> !transform.any_op2380 %p2 = transform.num_associations %4 : (!transform.any_op) -> !transform.param<i64>2381 // expected-remark @below{{1}}2382 transform.debug.emit_param_as_remark %p2 : !transform.param<i64>2383 transform.yield2384 }2385}2386 2387 2388// -----2389 2390// expected-note @below {{target op}}2391module attributes {transform.with_named_sequence} {2392 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2393 // expected-error @below{{could not find a parent op that matches all requirements}}2394 %3 = transform.get_parent_op %arg0 {op_name = "builtin.module"} : (!transform.any_op) -> !transform.any_op2395 transform.yield2396 }2397}2398 2399// -----2400 2401func.func @cast(%arg0: f32) -> f64 {2402 // expected-remark @below{{f64}}2403 %0 = arith.extf %arg0 : f32 to f642404 return %0 : f642405}2406 2407module attributes {transform.with_named_sequence} {2408 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2409 %0 = transform.structured.match ops{["arith.extf"]} in %arg0 : (!transform.any_op) -> !transform.op<"arith.extf">2410 %1 = transform.get_result %0[0] : (!transform.op<"arith.extf">) -> !transform.any_value2411 %2 = transform.get_type %1 : (!transform.any_value) -> !transform.type2412 transform.debug.emit_param_as_remark %2 at %0 : !transform.type, !transform.op<"arith.extf">2413 transform.yield2414 }2415}2416 2417// -----2418 2419module attributes {transform.with_named_sequence} {2420 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2421 // expected-error @below {{expected type attribute, got 0 : i32}}2422 transform.test_produce_param (0 : i32) : !transform.type2423 transform.yield2424 }2425}2426 2427// -----2428 2429module attributes {transform.with_named_sequence} {2430 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2431 // expected-error @below {{expected affine map attribute, got 0 : i32}}2432 transform.test_produce_param (0 : i32) : !transform.affine_map2433 transform.yield2434 }2435}2436 2437// -----2438 2439// CHECK-LABEL: @type_param_anchor2440func.func private @type_param_anchor()2441 2442module attributes {transform.with_named_sequence} {2443 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2444 // CHECK: test_produce_param(f32) : !transform.type2445 transform.test_produce_param(f32) : !transform.type2446 transform.yield2447 }2448}2449 2450// -----2451 2452// CHECK-LABEL: @affine_map_param_anchor2453func.func private @affine_map_param_anchor()2454 2455module attributes {transform.with_named_sequence} {2456 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2457 // CHECK: test_produce_param(#{{.*}}) : !transform.affine_map2458 transform.test_produce_param(affine_map<(d0) -> ()>) : !transform.affine_map2459 transform.yield2460 }2461}2462 2463// -----2464 2465func.func @verify_success(%arg0: f64) -> f64 {2466 return %arg0 : f642467}2468 2469module attributes {transform.with_named_sequence} {2470 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2471 %0 = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op2472 transform.verify %0 : !transform.any_op2473 transform.yield2474 }2475}2476 2477// -----2478 2479// expected-error @below{{fail_to_verify is set}}2480// expected-note @below{{payload op}}2481func.func @verify_failure(%arg0: f64) -> f64 {2482 return %arg0 : f642483}2484 2485module attributes {transform.with_named_sequence} {2486 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2487 %0 = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op2488 transform.test_produce_invalid_ir %0 : !transform.any_op2489 // expected-error @below{{failed to verify payload op}}2490 transform.verify %0 : !transform.any_op2491 transform.yield2492 }2493}2494 2495// -----2496 2497func.func @select() {2498 // expected-remark @below{{found foo}}2499 "test.foo"() : () -> ()2500 // expected-remark @below{{found bar}}2501 "test.bar"() : () -> ()2502 // expected-remark @below{{found foo}}2503 "test.foo"() : () -> ()2504 func.return2505}2506 2507module attributes {transform.with_named_sequence} {2508 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2509 // Match all ops inside the function (including the function itself).2510 %func_op = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op2511 %0 = transform.structured.match in %func_op : (!transform.any_op) -> !transform.any_op2512 %p = transform.num_associations %0 : (!transform.any_op) -> !transform.param<i64>2513 // expected-remark @below{{5}}2514 transform.debug.emit_param_as_remark %p : !transform.param<i64>2515 2516 // Select "test.foo".2517 %foo = transform.select "test.foo" in %0 : (!transform.any_op) -> !transform.any_op2518 transform.debug.emit_remark_at %foo, "found foo" : !transform.any_op2519 2520 // Select "test.bar".2521 %bar = transform.select "test.bar" in %0 : (!transform.any_op) -> !transform.any_op2522 transform.debug.emit_remark_at %bar, "found bar" : !transform.any_op2523 transform.yield2524 }2525}2526 2527// -----2528 2529// CHECK-LABEL: func @apply_dce(2530// CHECK-NEXT: memref.store2531// CHECK-NEXT: return2532func.func @apply_dce(%f: f32, %m: memref<5xf32>, %idx: index) {2533 // Two dead ops, interleaved with a non-dead op.2534 %0 = tensor.empty() : tensor<5xf32>2535 memref.store %f, %m[%idx] : memref<5xf32>2536 %1 = tensor.insert %f into %0[%idx] : tensor<5xf32>2537 return2538}2539 2540module attributes {transform.with_named_sequence} {2541 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2542 %func_op = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op2543 %empty_op = transform.structured.match ops{["tensor.empty"]} in %func_op : (!transform.any_op) -> !transform.any_op2544 transform.apply_dce to %func_op : !transform.any_op2545 2546 %p = transform.num_associations %empty_op : (!transform.any_op) -> !transform.param<i64>2547 // expected-remark @below{{0}}2548 transform.debug.emit_param_as_remark %p : !transform.param<i64>2549 transform.yield2550 }2551}2552 2553 2554// -----2555 2556func.func @no_constant_under_loop(%lb: index, %ub: index, %step: index) {2557 scf.for %i= %lb to %ub step %step {2558 arith.constant 0 : index2559 }2560 return2561}2562 2563module @named_inclusion attributes { transform.with_named_sequence } {2564// Match `arith.constant`s that are not nested under a `scf.for` and ensure2565// there are none in the program2566 2567 transform.named_sequence @print(%root: !transform.any_op {transform.readonly}) {2568 transform.debug.emit_remark_at %root, "matched func" : !transform.any_op2569 transform.yield2570 }2571 2572 transform.named_sequence @match_constant_not_under_scf_for(%root: !transform.any_op {transform.readonly})2573 -> !transform.any_op {2574 transform.match.operation_name %root ["arith.constant"] : !transform.any_op2575 %for = transform.get_parent_op %root { op_name = "scf.for", allow_empty_results }2576 : (!transform.any_op) -> (!transform.any_op)2577 transform.match.operation_empty %for : !transform.any_op2578 transform.yield %root : !transform.any_op2579 }2580 2581 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2582 transform.foreach_match in %arg02583 @match_constant_not_under_scf_for -> @print2584 : (!transform.any_op) -> (!transform.any_op)2585 transform.yield2586 }2587}2588 2589// -----2590 2591func.func @no_constant_under_loop(%lb: index, %ub: index, %step: index) {2592 // expected-remark @below {{no parent scf.for}}2593 arith.constant 0 : index2594 return2595}2596 2597module @named_inclusion attributes { transform.with_named_sequence } {2598 // Match `arith.constant`s that are not nested under a `scf.for` and ensure2599 // there are none in the program2600 2601 transform.named_sequence @print(%root: !transform.any_op {transform.readonly}) {2602 transform.debug.emit_remark_at %root, "no parent scf.for" : !transform.any_op2603 transform.yield2604 }2605 2606 transform.named_sequence @match_constant_not_under_scf_for(%root: !transform.any_op {transform.readonly})2607 -> !transform.any_op {2608 transform.match.operation_name %root ["arith.constant"] : !transform.any_op2609 %for = transform.get_parent_op %root { op_name = "scf.for", allow_empty_results }2610 : (!transform.any_op) -> (!transform.any_op)2611 transform.match.operation_empty %for : !transform.any_op2612 transform.yield %root : !transform.any_op2613 }2614 2615 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2616 transform.foreach_match in %arg02617 @match_constant_not_under_scf_for -> @print2618 : (!transform.any_op) -> (!transform.any_op)2619 transform.yield2620 }2621}2622 2623// -----2624 2625module attributes { transform.with_named_sequence } {2626 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2627 // expected-error @below {{result #0, associated with 2 payload objects, expected 1}}2628 transform.collect_matching @matcher in %arg0 : (!transform.any_op) -> !transform.any_op2629 transform.yield2630 }2631 2632 transform.named_sequence @matcher(%arg0: !transform.any_op {transform.readonly}) -> !transform.any_op {2633 %0 = transform.merge_handles %arg0, %arg0 : !transform.any_op2634 transform.yield %0 : !transform.any_op2635 }2636}2637 2638// -----2639 2640module attributes { transform.with_named_sequence } {2641 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2642 // expected-error @below {{unresolved external symbol @matcher}}2643 transform.collect_matching @matcher in %arg0 : (!transform.any_op) -> !transform.any_op2644 transform.yield2645 }2646 2647 transform.named_sequence @matcher(%arg0: !transform.any_op {transform.readonly}) -> !transform.any_op2648}2649 2650// -----2651 2652module attributes { transform.with_named_sequence } {2653 transform.named_sequence @__transform_main(%arg0: !transform.any_op) {2654 // expected-remark @below {{matched}}2655 %0 = transform.collect_matching @matcher in %arg0 : (!transform.any_op) -> !transform.any_op2656 // expected-remark @below {{matched}}2657 transform.debug.emit_remark_at %0, "matched" : !transform.any_op2658 transform.yield2659 }2660 2661 transform.named_sequence @matcher(%arg0: !transform.any_op {transform.readonly}) -> !transform.any_op {2662 transform.match.operation_name %arg0 ["transform.debug.emit_remark_at", "transform.collect_matching"] : !transform.any_op2663 transform.yield %arg0 : !transform.any_op2664 }2665}2666