| // RUN: mlir-opt %s --transform-interpreter -allow-unregistered-dialect --split-input-file --verify-diagnostics | FileCheck %s |
| |
| // UNSUPPORTED: target=aarch64-pc-windows-msvc |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // expected-remark @below {{applying transformation}} |
| transform.test_transform_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %0 = transform.test_produce_self_handle_or_forward_operand { foo = "bar" } : () -> !transform.any_op |
| // expected-remark @below {{succeeded}} |
| transform.test_consume_operand_of_op_kind_or_fail %0, "transform.test_produce_self_handle_or_forward_operand" : !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %0 = transform.test_produce_self_handle_or_forward_operand { foo = "bar" } : () -> !transform.any_op |
| // 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}} |
| transform.test_consume_operand_of_op_kind_or_fail %0, "transform.sequence" : !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // It is okay to have multiple handles to the same payload op as long |
| // as only one of them is consumed. The expensive checks mode is necessary |
| // to detect double-consumption. |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %0 = transform.test_produce_self_handle_or_forward_operand { foo = "bar" } : () -> !transform.any_op |
| %1 = transform.test_copy_payload %0 : (!transform.any_op) -> !transform.any_op |
| // expected-remark @below {{succeeded}} |
| transform.test_consume_operand_of_op_kind_or_fail %0, "transform.test_produce_self_handle_or_forward_operand" : !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb0(%arg1: !transform.any_op): |
| // expected-remark @below {{applying transformation "a"}} |
| test_transform_op "a" |
| // expected-remark @below {{applying transformation "b"}} |
| test_transform_op "b" |
| // expected-remark @below {{applying transformation "c"}} |
| test_transform_op "c" |
| } |
| // expected-remark @below {{applying transformation "d"}} |
| transform.test_transform_op "d" |
| // expected-remark @below {{applying transformation "e"}} |
| transform.test_transform_op "e" |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %0 = transform.test_produce_self_handle_or_forward_operand : () -> !transform.any_op |
| transform.sequence %0 : !transform.any_op failures(propagate) { |
| ^bb0(%arg1: !transform.any_op): |
| // expected-remark @below {{succeeded}} |
| test_consume_operand_of_op_kind_or_fail %arg1, "transform.test_produce_self_handle_or_forward_operand" : !transform.any_op |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %0 = transform.sequence %arg0 : !transform.any_op -> !transform.any_op failures(propagate) { |
| ^bb0(%arg1: !transform.any_op): |
| %1 = test_produce_self_handle_or_forward_operand : () -> !transform.any_op |
| yield %1 : !transform.any_op |
| } |
| // expected-remark @below {{succeeded}} |
| transform.test_consume_operand_of_op_kind_or_fail %0, "transform.test_produce_self_handle_or_forward_operand" : !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // expected-remark @below {{parent function}} |
| func.func @foo() { |
| %0 = arith.constant 0 : i32 |
| return |
| } |
| |
| // expected-remark @below {{parent function}} |
| func.func @bar() { |
| %0 = arith.constant 0 : i32 |
| %1 = arith.constant 1 : i32 |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @const : benefit(1) { |
| %r = pdl.types |
| %0 = pdl.operation "arith.constant" -> (%r : !pdl.range<type>) |
| pdl.rewrite %0 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb1(%arg1: !transform.any_op): |
| %f = pdl_match @const in %arg1 : (!transform.any_op) -> !transform.any_op |
| %m = get_parent_op %f {isolated_from_above} : (!transform.any_op) -> !transform.any_op |
| transform.debug.emit_remark_at %m, "parent function" : !transform.any_op |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @test_get_nth_parent() { |
| "test.foo"() ({ |
| // expected-remark @below{{2nd parent}} |
| "test.foo"() ({ |
| "test.qux"() ({ |
| // expected-remark @below{{1st parent}} |
| "test.foo"() ({ |
| "test.bar"() : () -> () |
| }) : () -> () |
| }) : () -> () |
| }) : () -> () |
| }) : () -> () |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %f = transform.structured.match ops{["test.bar"]} in %arg0 : (!transform.any_op) -> !transform.any_op |
| %parent = transform.get_parent_op %f {nth_parent = 1, op_name = "test.foo"} : (!transform.any_op) -> !transform.any_op |
| transform.debug.emit_remark_at %parent, "1st parent" : !transform.any_op |
| %parent2 = transform.get_parent_op %f {nth_parent = 2, op_name = "test.foo"} : (!transform.any_op) -> !transform.any_op |
| transform.debug.emit_remark_at %parent2, "2nd parent" : !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @foo() { |
| %0 = arith.constant 0 : i32 |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @match_func : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "func.func"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb1(%arg1: !transform.any_op): |
| // This is necessary to run the transformation on something other than the |
| // top-level module, "alternatives" cannot be run on that. |
| %0 = pdl_match @match_func in %arg1 : (!transform.any_op) -> !transform.any_op |
| transform.alternatives %0 : !transform.any_op { |
| ^bb2(%arg2: !transform.any_op): |
| %1 = transform.test_produce_self_handle_or_forward_operand : () -> !transform.any_op |
| // This operation fails, which triggers the next alternative without |
| // reporting the error. |
| transform.test_consume_operand_of_op_kind_or_fail %1, "transform.sequence" : !transform.any_op |
| }, { |
| ^bb2(%arg2: !transform.any_op): |
| %1 = transform.test_produce_self_handle_or_forward_operand : () -> !transform.any_op |
| // expected-remark @below {{succeeded}} |
| transform.test_consume_operand_of_op_kind_or_fail %1, "transform.test_produce_self_handle_or_forward_operand" : !transform.any_op |
| } |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func private @bar() |
| |
| func.func @foo() { |
| call @bar() : () -> () |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @match_call : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "func.call"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb1(%arg1: !transform.any_op): |
| %0 = pdl_match @match_call in %arg1 : (!transform.any_op) -> !transform.any_op |
| %1 = get_parent_op %0 {isolated_from_above} : (!transform.any_op) -> !transform.any_op |
| // expected-error @below {{all alternatives failed}} |
| transform.alternatives %1 : !transform.any_op { |
| ^bb2(%arg2: !transform.any_op): |
| %2 = transform.pdl_match @match_call in %arg2 : (!transform.any_op) -> !transform.any_op |
| // expected-remark @below {{applying}} |
| transform.test_emit_remark_and_erase_operand %2, "applying" {fail_after_erase} : !transform.any_op |
| } |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func private @bar() |
| |
| func.func @foo() { |
| // expected-remark @below {{still here}} |
| call @bar() : () -> () |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @match_call : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "func.call"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb1(%arg1: !transform.any_op): |
| %0 = pdl_match @match_call in %arg1 : (!transform.any_op) -> !transform.any_op |
| %1 = get_parent_op %0 {isolated_from_above} : (!transform.any_op) -> !transform.any_op |
| transform.alternatives %1 : !transform.any_op { |
| ^bb2(%arg2: !transform.any_op): |
| %2 = transform.pdl_match @match_call in %arg2 : (!transform.any_op) -> !transform.any_op |
| // expected-remark @below {{applying}} |
| transform.test_emit_remark_and_erase_operand %2, "applying" {fail_after_erase} : !transform.any_op |
| }, { |
| ^bb2(%arg2: !transform.any_op): |
| %2 = transform.pdl_match @match_call in %arg2 : (!transform.any_op) -> !transform.any_op |
| transform.debug.emit_remark_at %2, "still here" : !transform.any_op |
| // This alternative succeeds. |
| }, { |
| ^bb2(%arg2: !transform.any_op): |
| // This alternative is never run, so we must not have a remark here. |
| %2 = transform.pdl_match @match_call in %arg2 : (!transform.any_op) -> !transform.any_op |
| transform.test_emit_remark_and_erase_operand %2, "should not happen" {fail_after_erase} : !transform.any_op |
| } |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func private @bar() |
| |
| func.func @erase_call() { |
| call @bar() : () -> () |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @match_call : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "func.call"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb1(%arg1: !transform.any_op): |
| %0 = pdl_match @match_call in %arg1 : (!transform.any_op) -> !transform.any_op |
| %1 = get_parent_op %0 {isolated_from_above} : (!transform.any_op) -> !transform.any_op |
| transform.alternatives %1 : !transform.any_op { |
| ^bb2(%arg2: !transform.any_op): |
| %2 = transform.pdl_match @match_call in %arg2 : (!transform.any_op) -> !transform.any_op |
| // expected-remark @below {{applying}} |
| transform.test_emit_remark_and_erase_operand %2, "applying" {fail_after_erase} : !transform.any_op |
| }, { |
| ^bb2(%arg2: !transform.any_op): |
| %2 = transform.pdl_match @match_call in %arg2 : (!transform.any_op) -> !transform.any_op |
| // expected-remark @below {{applying second time}} |
| transform.test_emit_remark_and_erase_operand %2, "applying second time" : !transform.any_op |
| } |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func private @bar() |
| |
| func.func @foo() { |
| call @bar() : () -> () |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @match_call : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "func.call"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb1(%arg1: !transform.any_op): |
| %0 = pdl_match @match_call in %arg1 : (!transform.any_op) -> !transform.any_op |
| %1 = get_parent_op %0 {isolated_from_above} : (!transform.any_op) -> !transform.any_op |
| %2 = transform.alternatives %1 : !transform.any_op -> !transform.any_op { |
| ^bb2(%arg2: !transform.any_op): |
| %3 = transform.pdl_match @match_call in %arg2 : (!transform.any_op) -> !transform.any_op |
| // expected-remark @below {{applying}} |
| transform.test_emit_remark_and_erase_operand %3, "applying" {fail_after_erase} : !transform.any_op |
| %4 = transform.test_produce_self_handle_or_forward_operand %3 : (!transform.any_op) -> !transform.any_op |
| transform.yield %4 : !transform.any_op |
| }, { |
| ^bb2(%arg2: !transform.any_op): |
| %4 = transform.test_produce_self_handle_or_forward_operand : () -> !transform.any_op |
| transform.yield %4 : !transform.any_op |
| } |
| // The first alternative failed, so the returned value is taken from the |
| // second alternative, associated test_produce_self_handle_or_forward_operand rather |
| // than pdl_match. |
| // expected-remark @below {{succeeded}} |
| transform.test_consume_operand_of_op_kind_or_fail %2, "transform.test_produce_self_handle_or_forward_operand" : !transform.any_op |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // expected-note @below {{scope}} |
| module attributes {transform.with_named_sequence} { |
| func.func @foo() { |
| %0 = arith.constant 0 : i32 |
| return |
| } |
| |
| func.func @bar() { |
| %0 = arith.constant 0 : i32 |
| %1 = arith.constant 1 : i32 |
| return |
| } |
| |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| // expected-error @below {{scope must not contain the transforms being applied}} |
| transform.alternatives %arg1 : !transform.any_op { |
| ^bb2(%arg2: !transform.any_op): |
| %0 = transform.test_produce_self_handle_or_forward_operand : () -> !transform.any_op |
| transform.test_consume_operand_of_op_kind_or_fail %0, "transform.sequence" : !transform.any_op |
| }, { |
| ^bb2(%arg2: !transform.any_op): |
| %0 = transform.test_produce_self_handle_or_forward_operand : () -> !transform.any_op |
| transform.test_consume_operand_of_op_kind_or_fail %0, "transform.test_produce_self_handle_or_forward_operand" : !transform.any_op |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @foo(%arg0: index, %arg1: index, %arg2: index) { |
| // expected-note @below {{scope}} |
| scf.for %i = %arg0 to %arg1 step %arg2 { |
| %0 = arith.constant 0 : i32 |
| } |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @match_const : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "arith.constant"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| |
| |
| sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb1(%arg1: !transform.any_op): |
| %0 = transform.pdl_match @match_const in %arg1 : (!transform.any_op) -> !transform.any_op |
| %1 = transform.get_parent_op %0 {op_name = "scf.for"} : (!transform.any_op) -> !transform.any_op |
| // expected-error @below {{only isolated-from-above ops can be alternative scopes}} |
| alternatives %1 : !transform.any_op { |
| ^bb2(%arg2: !transform.any_op): |
| } |
| } |
| } |
| transform.yield |
| } |
| } |
| // ----- |
| |
| func.func @foo() { |
| // expected-note @below {{when applied to this op}} |
| "op" () : () -> () |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @some : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "op"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb0(%arg1: !transform.any_op): |
| %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op |
| // expected-error @below {{application of transform.test_wrong_number_of_results expected to produce 3 results (actually produced 1).}} |
| // expected-note @below {{if you need variadic results, consider a generic `apply` instead of the specialized `applyToOne`.}} |
| transform.test_wrong_number_of_results %0 : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op) |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @foo() { |
| "op" () : () -> () |
| // expected-note @below {{when applied to this op}} |
| "op" () : () -> () |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @some : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "op"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb0(%arg1: !transform.any_op): |
| %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op |
| // expected-error @below {{application of transform.test_wrong_number_of_multi_results expected to produce 1 results (actually produced 0)}} |
| // expected-note @below {{if you need variadic results, consider a generic `apply` instead of the specialized `applyToOne`.}} |
| transform.test_wrong_number_of_multi_results %0 : (!transform.any_op) -> (!transform.any_op) |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @foo() { |
| "op" () : () -> () |
| "op" () : () -> () |
| "op" () : () -> () |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @some : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "op"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb0(%arg1: !transform.any_op): |
| %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op |
| // Transform matches 3 ops and produces 2 results. |
| %1:2 = transform.test_correct_number_of_multi_results %0 : (!transform.any_op) -> (!transform.any_op, !transform.any_op) |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @foo() { |
| "wrong_op_name" () : () -> () |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @some : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "op"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb0(%arg1: !transform.any_op): |
| %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op |
| // Transform fails to match any but still produces 2 results. |
| %1:2 = transform.test_correct_number_of_multi_results %0 : (!transform.any_op) -> (!transform.any_op, !transform.any_op) |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // This should not fail. |
| |
| func.func @foo() { |
| "op" () : () -> () |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @some : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "op"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb0(%arg1: !transform.any_op): |
| %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op |
| transform.test_mixed_null_and_non_null_results %0 : (!transform.any_op) -> (!transform.any_op, !transform.any_op) |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // Expecting to match all operations by merging the handles that matched addi |
| // and subi separately. |
| func.func @foo(%arg0: index) { |
| // expected-remark @below {{matched}} |
| %0 = arith.addi %arg0, %arg0 : index |
| // expected-remark @below {{matched}} |
| %1 = arith.subi %arg0, %arg0 : index |
| // expected-remark @below {{matched}} |
| %2 = arith.addi %0, %1 : index |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @addi : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "arith.addi"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| pdl.pattern @subi : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "arith.subi"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb0(%arg1: !transform.any_op): |
| %0 = pdl_match @addi in %arg1 : (!transform.any_op) -> !transform.any_op |
| %1 = pdl_match @subi in %arg1 : (!transform.any_op) -> !transform.any_op |
| %2 = merge_handles %0, %1 : !transform.any_op |
| transform.debug.emit_remark_at %2, "matched" : !transform.any_op |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @foo(%arg0: index) { |
| %0 = arith.addi %arg0, %arg0 : index |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @addi : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "arith.addi"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb0(%arg1: !transform.any_op): |
| %0 = pdl_match @addi in %arg1 : (!transform.any_op) -> !transform.any_op |
| %1 = pdl_match @addi in %arg1 : (!transform.any_op) -> !transform.any_op |
| %2 = merge_handles deduplicate %0, %1 : !transform.any_op |
| %3 = num_associations %2 : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below {{1}} |
| transform.debug.emit_param_as_remark %3 : !transform.param<i64> |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @foo() { |
| "op" () { target_me } : () -> () |
| // expected-note @below {{when applied to this op}} |
| "op" () : () -> () |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @some : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "op"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb0(%arg1: !transform.any_op): |
| %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op |
| // expected-error @below {{failed to apply}} |
| transform.test_mixed_success_and_silenceable %0 : !transform.any_op |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @foo() { |
| "op" () : () -> () |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @some : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "op"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(suppress) { |
| ^bb0(%arg1: !transform.any_op): |
| %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op |
| // Not expecting error here because we are suppressing it. |
| // expected-remark @below {{foo}} |
| test_emit_remark_and_erase_operand %0, "foo" {fail_after_erase} : !transform.any_op |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @foo() { |
| "op" () : () -> () |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @some : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "op"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb0(%arg1: !transform.any_op): |
| %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op |
| // expected-error @below {{silenceable error}} |
| // expected-remark @below {{foo}} |
| test_emit_remark_and_erase_operand %0, "foo" {fail_after_erase} : !transform.any_op |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| func.func private @foo() |
| func.func private @bar() |
| |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @func : benefit(1) { |
| %0 = pdl.operands |
| %1 = pdl.types |
| %2 = pdl.operation "func.func"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>) |
| pdl.rewrite %2 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb0(%arg1: !transform.any_op): |
| %0 = pdl_match @func in %arg1 : (!transform.any_op) -> !transform.any_op |
| %1 = replicate num(%0) %arg1 : !transform.any_op, !transform.any_op |
| %p = num_associations %1 : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below {{2}} |
| transform.debug.emit_param_as_remark %p : !transform.param<i64> |
| %2 = replicate num(%0) %1 : !transform.any_op, !transform.any_op |
| %p2 = num_associations %2 : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below {{4}} |
| transform.debug.emit_param_as_remark %p2 : !transform.param<i64> |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @bar() { |
| // expected-remark @below {{transform applied}} |
| %0 = arith.constant 0 : i32 |
| // expected-remark @below {{transform applied}} |
| %1 = arith.constant 1 : i32 |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @const : benefit(1) { |
| %r = pdl.types |
| %0 = pdl.operation "arith.constant" -> (%r : !pdl.range<type>) |
| pdl.rewrite %0 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb1(%arg1: !transform.any_op): |
| %f = pdl_match @const in %arg1 : (!transform.any_op) -> !transform.any_op |
| transform.foreach %f : !transform.any_op { |
| ^bb2(%arg2: !transform.any_op): |
| %p = transform.num_associations %arg2 : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below {{1}} |
| transform.debug.emit_param_as_remark %p : !transform.param<i64> |
| transform.debug.emit_remark_at %arg2, "transform applied" : !transform.any_op |
| } |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // CHECK-LABEL: func @consume_in_foreach() |
| // CHECK-NEXT: return |
| func.func @consume_in_foreach() { |
| %0 = arith.constant 0 : index |
| %1 = arith.constant 1 : index |
| %2 = arith.constant 2 : index |
| %3 = arith.constant 3 : index |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %f = transform.structured.match ops{["arith.constant"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| transform.foreach %f : !transform.any_op { |
| ^bb2(%arg2: !transform.any_op): |
| // expected-remark @below {{erasing}} |
| transform.test_emit_remark_and_erase_operand %arg2, "erasing" : !transform.any_op |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @bar() { |
| scf.execute_region { |
| // expected-remark @below {{transform applied}} |
| %0 = arith.constant 0 : i32 |
| scf.yield |
| } |
| |
| scf.execute_region { |
| // expected-remark @below {{transform applied}} |
| %1 = arith.constant 1 : i32 |
| // expected-remark @below {{transform applied}} |
| %2 = arith.constant 2 : i32 |
| scf.yield |
| } |
| |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @const : benefit(1) { |
| %r = pdl.types |
| %0 = pdl.operation "arith.constant" -> (%r : !pdl.range<type>) |
| pdl.rewrite %0 with "transform.dialect" |
| } |
| |
| pdl.pattern @execute_region : benefit(1) { |
| %r = pdl.types |
| %0 = pdl.operation "scf.execute_region" -> (%r : !pdl.range<type>) |
| pdl.rewrite %0 with "transform.dialect" |
| } |
| |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb1(%arg1: !transform.any_op): |
| %f = pdl_match @execute_region in %arg1 : (!transform.any_op) -> !transform.any_op |
| %results = transform.foreach %f : !transform.any_op -> !transform.any_op { |
| ^bb2(%arg2: !transform.any_op): |
| %g = transform.pdl_match @const in %arg2 : (!transform.any_op) -> !transform.any_op |
| transform.yield %g : !transform.any_op |
| } |
| |
| %p = transform.num_associations %results : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below {{3}} |
| transform.debug.emit_param_as_remark %p : !transform.param<i64> |
| transform.debug.emit_remark_at %results, "transform applied" : !transform.any_op |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @get_parent_for_op_no_loop(%arg0: index, %arg1: index) { |
| // expected-remark @below {{found muli}} |
| %0 = arith.muli %arg0, %arg1 : index |
| arith.addi %0, %arg1 : index |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %addi = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| %muli = transform.get_producer_of_operand %addi[0] : (!transform.any_op) -> !transform.any_op |
| transform.debug.emit_remark_at %muli, "found muli" : !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @get_parent_for_op_no_loop(%arg0: index, %arg1: index) { |
| // expected-note @below {{target op}} |
| %0 = arith.muli %arg0, %arg1 : index |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %muli = transform.structured.match ops{["arith.muli"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| // expected-error @below {{could not find a producer for operand number: 0 of}} |
| %bbarg = transform.get_producer_of_operand %muli[0] : (!transform.any_op) -> !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @get_consumer(%arg0: index, %arg1: index) { |
| %0 = arith.muli %arg0, %arg1 : index |
| // expected-remark @below {{found addi}} |
| arith.addi %0, %arg1 : index |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %muli = transform.structured.match ops{["arith.muli"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| %addi = transform.get_consumers_of_result %muli[0] : (!transform.any_op) -> !transform.any_op |
| transform.debug.emit_remark_at %addi, "found addi" : !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @get_consumer_fail_1(%arg0: index, %arg1: index) { |
| %0 = arith.muli %arg0, %arg1 : index |
| %1 = arith.muli %arg0, %arg1 : index |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %muli = transform.structured.match ops{["arith.muli"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| // expected-error @below {{handle must be mapped to exactly one payload op}} |
| %bbarg = transform.get_consumers_of_result %muli[0] : (!transform.any_op) -> !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @get_consumer_fail_2(%arg0: index, %arg1: index) { |
| %0 = arith.muli %arg0, %arg1 : index |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %muli = transform.structured.match ops{["arith.muli"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| // expected-error @below {{result number overflow}} |
| %bbarg = transform.get_consumers_of_result %muli[1] : (!transform.any_op) -> !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @split_handle(%a: index, %b: index, %c: index) { |
| %0 = arith.muli %a, %b : index |
| %1 = arith.muli %a, %c : index |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%fun: !transform.any_op) { |
| %muli = transform.structured.match ops{["arith.muli"]} in %fun : (!transform.any_op) -> !transform.any_op |
| %h:2 = transform.split_handle %muli : (!transform.any_op) -> (!transform.any_op, !transform.any_op) |
| %p = transform.num_associations %h#0 : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below {{1}} |
| transform.debug.emit_param_as_remark %p : !transform.param<i64> |
| %muli_2 = transform.structured.match ops{["arith.muli"]} in %fun : (!transform.any_op) -> !transform.any_op |
| // expected-error @below {{expected to contain 3 payload ops but it contains 2 payload ops}} |
| %h_2:3 = transform.split_handle %muli_2 : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op) |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @split_handle(%a: index, %b: index, %c: index) { |
| %0 = arith.muli %a, %b : index |
| %1 = arith.muli %a, %c : index |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.sequence %root : !transform.any_op failures(suppress) { |
| ^bb1(%fun: !transform.any_op): |
| %muli = transform.structured.match ops{["arith.muli"]} in %fun : (!transform.any_op) -> !transform.any_op |
| %h:2 = split_handle %muli : (!transform.any_op) -> (!transform.any_op, !transform.any_op) |
| %p = transform.num_associations %h#0 : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below {{1}} |
| transform.debug.emit_param_as_remark %p : !transform.param<i64> |
| %muli_2 = transform.structured.match ops{["arith.muli"]} in %fun : (!transform.any_op) -> !transform.any_op |
| // Silenceable failure and all handles are now empty. |
| %h_2:3 = split_handle %muli_2 : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op) |
| %p2 = transform.num_associations %h_2#0 : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below {{0}} |
| transform.debug.emit_param_as_remark %p2 : !transform.param<i64> |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @split_handle(%a: index, %b: index, %c: index) { |
| %0 = arith.muli %a, %b : index |
| %1 = arith.muli %a, %c : index |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%fun: !transform.any_op) { |
| %muli_2 = transform.structured.match ops{["arith.muli"]} in %fun : (!transform.any_op) -> !transform.any_op |
| // No error, last result handle is empty. |
| %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) |
| %p = transform.num_associations %h#0 : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below {{1}} |
| transform.debug.emit_param_as_remark %p : !transform.param<i64> |
| %p2 = transform.num_associations %h#1 : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below {{1}} |
| transform.debug.emit_param_as_remark %p2 : !transform.param<i64> |
| %p3 = transform.num_associations %h#2 : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below {{0}} |
| transform.debug.emit_param_as_remark %p3 : !transform.param<i64> |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @split_handle(%a: index, %b: index, %c: index) { |
| %0 = arith.muli %a, %b : index |
| %1 = arith.muli %a, %c : index |
| %2 = arith.muli %a, %c : index |
| %3 = arith.muli %a, %c : index |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%fun: !transform.any_op) { |
| %muli_2 = transform.structured.match ops{["arith.muli"]} in %fun : (!transform.any_op) -> !transform.any_op |
| %h:2 = transform.split_handle %muli_2 {overflow_result = 0} : (!transform.any_op) -> (!transform.any_op, !transform.any_op) |
| %p = transform.num_associations %h#0 : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below {{3}} |
| transform.debug.emit_param_as_remark %p : !transform.param<i64> |
| %p2 = transform.num_associations %h#1 : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below {{1}} |
| transform.debug.emit_param_as_remark %p2 : !transform.param<i64> |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| "test.some_op"() : () -> () |
| "other_dialect.other_op"() : () -> () |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @some : benefit(1) { |
| %0 = pdl.operation "test.some_op" |
| pdl.rewrite %0 with "transform.dialect" |
| } |
| |
| sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb1(%arg1: !transform.any_op): |
| %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op |
| %2 = transform.cast %0 : !transform.any_op to !transform.test_dialect_op |
| transform.cast %2 : !transform.test_dialect_op to !transform.any_op |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| "test.some_op"() : () -> () |
| "other_dialect.other_op"() : () -> () |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @other : benefit(1) { |
| %0 = pdl.operation "other_dialect.other_op" |
| pdl.rewrite %0 with "transform.dialect" |
| } |
| |
| sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb1(%arg1: !transform.any_op): |
| %0 = pdl_match @other in %arg1 : (!transform.any_op) -> !transform.any_op |
| // expected-error @below {{expected the payload operation to belong to the 'test' dialect}} |
| %2 = transform.cast %0 : !transform.any_op to !transform.test_dialect_op |
| transform.cast %2 : !transform.test_dialect_op to !transform.any_op |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| "test.some_op"() : () -> () |
| "other_dialect.other_op"() : () -> () |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @some : benefit(1) { |
| %0 = pdl.operation "test.some_op" |
| pdl.rewrite %0 with "transform.dialect" |
| } |
| |
| sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb1(%arg1: !transform.any_op): |
| %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op |
| %2 = transform.cast %0 : !transform.any_op to !transform.op<"test.some_op"> |
| transform.cast %2 : !transform.op<"test.some_op"> to !transform.any_op |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| "test.some_op"() : () -> () |
| // expected-note @below {{payload operation}} |
| "other_dialect.other_op"() : () -> () |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| pdl.pattern @other : benefit(1) { |
| %0 = pdl.operation "other_dialect.other_op" |
| pdl.rewrite %0 with "transform.dialect" |
| } |
| |
| sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb1(%arg1: !transform.any_op): |
| %0 = pdl_match @other in %arg1 : (!transform.any_op) -> !transform.any_op |
| // expected-error @below {{incompatible payload operation name}} |
| %2 = transform.cast %0 : !transform.any_op to !transform.op<"test.some_op"> |
| transform.cast %2 : !transform.op<"test.some_op"> to !transform.any_op |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.with_pdl_patterns %root : !transform.any_op { |
| ^bb0(%arg0: !transform.any_op): |
| transform.sequence %arg0 : !transform.any_op failures(propagate) { |
| ^bb0(%arg1: !transform.any_op): |
| %0 = pdl_match @some in %arg1 : (!transform.any_op) -> !transform.any_op |
| // here, the handles nested under are {%root, %arg0, %arg1, %0} |
| // expected-remark @below {{4 handles nested under}} |
| transform.test_report_number_of_tracked_handles_nested_under %arg1 : !transform.any_op |
| // expected-remark @below {{erased}} |
| transform.test_emit_remark_and_erase_operand %0, "erased" : !transform.any_op |
| // here, the handles nested under are only {%root, %arg0, %arg1} |
| // expected-remark @below {{3 handles nested under}} |
| transform.test_report_number_of_tracked_handles_nested_under %arg1 : !transform.any_op |
| } |
| |
| pdl.pattern @some : benefit(1) { |
| %0 = pdl.operation "test.some_op" |
| pdl.rewrite %0 with "transform.dialect" |
| } |
| } |
| transform.yield |
| } |
| } |
| |
| "test.some_op"() : () -> () |
| |
| // ----- |
| |
| func.func @split_handle(%a: index, %b: index, %c: index) { |
| %0 = arith.muli %a, %b : index |
| %1 = arith.muli %a, %c : index |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.sequence %root : !transform.any_op -> !transform.any_op failures(propagate) { |
| ^bb1(%fun: !transform.any_op): |
| %muli = transform.structured.match ops{["arith.muli"]} in %fun : (!transform.any_op) -> !transform.any_op |
| // expected-error @below {{expected to contain 3 payload ops but it contains 2 payload ops}} |
| %h_2:3 = split_handle %muli : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op) |
| /// Test that yield does not crash in the presence of silenceable error in |
| /// propagate mode. |
| yield %fun : !transform.any_op |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.sequence %root : !transform.any_op -> !transform.any_op failures(suppress) { |
| ^bb0(%arg0: !transform.any_op): |
| %muli = transform.structured.match ops{["arith.muli"]} in %arg0 : (!transform.any_op) -> !transform.any_op |
| // Edge case propagating empty handles in splitting. |
| %0:3 = split_handle %muli : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op) |
| // Test does not crash when accessing the empty handle. |
| yield %0#0 : !transform.any_op |
| } |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %0 = transform.test_produce_param (0 : i32) : !transform.test_dialect_param |
| // expected-remark @below {{0 : i32}} |
| transform.debug.emit_param_as_remark %0 : !transform.test_dialect_param |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // expected-error @below {{expected the type of the parameter attribute ('i32') to match the parameter type ('i64')}} |
| transform.test_produce_param (0 : i32) : !transform.param<i64> |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %0 = transform.test_add_to_param 40 |
| %1 = transform.test_add_to_param %0, 2 |
| // expected-remark @below {{42 : i32}} |
| transform.debug.emit_param_as_remark %1 : !transform.test_dialect_param |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %0 = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op |
| %1 = transform.test_produce_param_with_number_of_test_ops %0 : !transform.any_op |
| // expected-remark @below {{1 : i32, 3 : i32}} |
| transform.debug.emit_param_as_remark %1 : !transform.test_dialect_param |
| %2 = transform.test_add_to_param %1, 100 |
| // expected-remark @below {{101 : i32, 103 : i32}} |
| transform.debug.emit_param_as_remark %2 : !transform.test_dialect_param |
| transform.yield |
| } |
| } |
| |
| func.func private @one_test_op(%arg0: i32) { |
| "test.op_a"(%arg0) { attr = 0 : i32} : (i32) -> i32 |
| return |
| } |
| |
| func.func private @three_test_ops(%arg0: i32) { |
| "test.op_a"(%arg0) { attr = 0 : i32} : (i32) -> i32 |
| "test.op_a"(%arg0) { attr = 0 : i32} : (i32) -> i32 |
| "test.op_a"(%arg0) { attr = 0 : i32} : (i32) -> i32 |
| return |
| } |
| |
| // ----- |
| |
| // expected-note @below {{when applied to this op}} |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // expected-error @below {{expected to produce an Operation * for result #0}} |
| transform.test_produce_transform_param_or_forward_operand %arg0 |
| { first_result_is_param } |
| : (!transform.any_op) -> (!transform.any_op, !transform.param<i64>) |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // Should not fail. |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| transform.test_produce_transform_param_or_forward_operand %arg0 |
| { first_result_is_null } |
| : (!transform.any_op) -> (!transform.any_op, !transform.param<i64>) |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // expected-note @below {{when applied to this op}} |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // expected-error @below {{expected to produce an Attribute for result #1}} |
| transform.test_produce_transform_param_or_forward_operand %arg0 |
| { second_result_is_handle } |
| : (!transform.any_op) -> (!transform.any_op, !transform.param<i64>) |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // expected-note @below {{when applied to this op}} |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // expected-error @below {{expected to produce a Value for result #0}} |
| transform.test_produce_transform_param_or_forward_operand %arg0 |
| { second_result_is_handle } |
| : (!transform.any_op) -> (!transform.any_value, !transform.param<i64>) |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // expected-error @below {{attempting to assign a null payload op to this transform value}} |
| %0 = transform.test_produce_null_payload : !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // expected-error @below {{attempting to assign a null parameter to this transform value}} |
| %0 = transform.test_produce_null_param : !transform.param<i64> |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // expected-error @below {{attempting to assign a null payload value to this transform handle}} |
| %0 = transform.test_produce_null_value : !transform.any_value |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // expected-error @below {{could not find a nested named sequence with name: __transform_main}} |
| module { |
| } |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| // expected-remark @below {{value handle}} |
| // expected-note @below {{value handle points to a block argument #0 in block #0 in region #0}} |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %0 = transform.test_produce_value_handle_to_self_operand %arg0 : (!transform.any_op) -> !transform.any_value |
| transform.debug.emit_remark_at %0, "value handle" : !transform.any_value |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // expected-remark @below {{result handle}} |
| // expected-note @below {{value handle points to an op result #1}} |
| %0:2 = "test.get_two_results"() : () -> (i32, i32) |
| // expected-remark @below {{result handle}} |
| // expected-note @below {{value handle points to an op result #1}} |
| %1:3 = "test.get_three_results"() : () -> (i32, i32, f32) |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %2 = transform.structured.match ops{["test.get_two_results", "test.get_three_results"]} in %arg0 : (!transform.any_op) -> !transform.any_op |
| %3 = transform.test_produce_value_handle_to_result %2, 1 : (!transform.any_op) -> !transform.any_value |
| transform.debug.emit_remark_at %3, "result handle" : !transform.any_value |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| "test.op_with_regions"() ({ |
| ^bb0: |
| "test.regon_terminator"() : () -> () |
| }, { |
| ^bb1: |
| "test.regon_terminator"() : () -> () |
| // expected-remark @below {{block argument handle}} |
| // expected-note @below {{value handle points to a block argument #2 in block #1 in region #1}} |
| ^bb2(%arg0: i32, %arg1: f64, %arg3: index): |
| "test.match_anchor"() : () -> () |
| "test.regon_terminator"() : () -> () |
| }) : () -> () |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %2 = transform.structured.match ops{["test.match_anchor"]} in %arg0 : (!transform.any_op) -> !transform.any_op |
| %3 = transform.test_produce_value_handle_to_argument_of_parent_block %2, 2 : (!transform.any_op) -> !transform.any_value |
| transform.debug.emit_remark_at %3, "block argument handle" : !transform.any_value |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // expected-note @below {{value defined here with type '!transform.test_dialect_param'}} |
| %0 = transform.test_produce_param_with_number_of_test_ops %arg0 : !transform.any_op |
| // expected-error @below {{unexpectedly consumed a value that is not a handle as operand #0}} |
| transform.test_consume_operand %0 : !transform.test_dialect_param |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // expected-remark @below {{addi operand}} |
| // expected-note @below {{value handle points to a block argument #0}} |
| func.func @get_operand_of_op(%arg0: index, %arg1: index) -> index { |
| %r = arith.addi %arg0, %arg1 : index |
| return %r : index |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %addi = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| %operand = transform.get_operand %addi[0] : (!transform.any_op) -> !transform.any_value |
| transform.debug.emit_remark_at %operand, "addi operand" : !transform.any_value |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @get_out_of_bounds_operand_of_op(%arg0: index, %arg1: index) -> index { |
| // expected-note @below {{while considering positions of this payload operation}} |
| %r = arith.addi %arg0, %arg1 : index |
| return %r : index |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %addi = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| // expected-error @below {{position overflow 2 (updated from 2) for maximum 2}} |
| %operand = transform.get_operand %addi[2] : (!transform.any_op) -> !transform.any_value |
| transform.debug.emit_remark_at %operand, "addi operand" : !transform.any_value |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // expected-remark @below {{addi operand}} |
| // expected-note @below {{value handle points to a block argument #1}} |
| func.func @get_inverted_operand_of_op(%arg0: index, %arg1: index) -> index { |
| %r = arith.addi %arg0, %arg1 : index |
| return %r : index |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %addi = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| %operand = transform.get_operand %addi[except(0)] : (!transform.any_op) -> !transform.any_value |
| transform.debug.emit_remark_at %operand, "addi operand" : !transform.any_value |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @get_multiple_operands_of_op(%arg0: index, %arg1: index) -> index { |
| %r = arith.addi %arg0, %arg1 : index |
| return %r : index |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %addui = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| %operands = transform.get_operand %addui[all] : (!transform.any_op) -> !transform.any_value |
| %p = transform.num_associations %operands : (!transform.any_value) -> !transform.param<i64> |
| // expected-remark @below {{2}} |
| transform.debug.emit_param_as_remark %p : !transform.param<i64> |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @get_result_of_op(%arg0: index, %arg1: index) -> index { |
| // expected-remark @below {{addi result}} |
| // expected-note @below {{value handle points to an op result #0}} |
| %r = arith.addi %arg0, %arg1 : index |
| return %r : index |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %addi = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| %result = transform.get_result %addi[0] : (!transform.any_op) -> !transform.any_value |
| transform.debug.emit_remark_at %result, "addi result" : !transform.any_value |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @get_out_of_bounds_result_of_op(%arg0: index, %arg1: index) -> index { |
| // expected-note @below {{while considering positions of this payload operation}} |
| %r = arith.addi %arg0, %arg1 : index |
| return %r : index |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %addi = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| // expected-error @below {{position overflow 1 (updated from 1) for maximum 1}} |
| %result = transform.get_result %addi[1] : (!transform.any_op) -> !transform.any_value |
| transform.debug.emit_remark_at %result, "addi result" : !transform.any_value |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @get_result_of_op(%arg0: index, %arg1: index) -> index { |
| // expected-remark @below {{matched}} |
| %r = arith.addi %arg0, %arg1 : index |
| return %r : index |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %addi = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| %result = transform.get_result %addi[0] : (!transform.any_op) -> !transform.any_value |
| %op = transform.get_defining_op %result : (!transform.any_value) -> !transform.any_op |
| transform.debug.emit_remark_at %op, "matched" : !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @get_multiple_result_of_op(%arg0: index, %arg1: index) -> (index, i1) { |
| %r, %b = arith.addui_extended %arg0, %arg1 : index, i1 |
| return %r, %b : index, i1 |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %addui = transform.structured.match ops{["arith.addui_extended"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| %results = transform.get_result %addui[all] : (!transform.any_op) -> !transform.any_value |
| %p = transform.num_associations %results : (!transform.any_value) -> !transform.param<i64> |
| // expected-remark @below {{2}} |
| transform.debug.emit_param_as_remark %p : !transform.param<i64> |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // expected-note @below {{target value}} |
| func.func @get_result_of_op_bbarg(%arg0: index, %arg1: index) -> index { |
| %r = arith.addi %arg0, %arg1 : index |
| return %r : index |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %addi = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| %bbarg = transform.test_produce_value_handle_to_argument_of_parent_block %addi, 0 : (!transform.any_op) -> !transform.any_value |
| // expected-error @below {{cannot get defining op of block argument}} |
| %op = transform.get_defining_op %bbarg : (!transform.any_value) -> !transform.any_op |
| transform.debug.emit_remark_at %op, "matched" : !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module @named_inclusion attributes { transform.with_named_sequence } { |
| |
| transform.named_sequence @foo(%arg0: !transform.any_op {transform.readonly}) -> () { |
| // expected-remark @below {{applying transformation "a"}} |
| transform.test_transform_op "a" |
| transform.yield |
| } |
| |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| transform.include @foo failures(propagate) (%arg0) : (!transform.any_op) -> () |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module @named_inclusion_in_named attributes { transform.with_named_sequence } { |
| |
| transform.named_sequence @foo(%arg0: !transform.any_op {transform.readonly}) -> () { |
| // expected-remark @below {{applying transformation "a"}} |
| transform.test_transform_op "a" |
| transform.yield |
| } |
| |
| transform.named_sequence @bar(%arg0: !transform.any_op {transform.readonly}) -> () { |
| // expected-remark @below {{applying transformation "b"}} |
| transform.test_transform_op "b" |
| transform.include @foo failures(propagate) (%arg0) : (!transform.any_op) -> () |
| transform.yield |
| } |
| |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| transform.include @bar failures(suppress) (%arg0) : (!transform.any_op) -> () |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // expected-remark @below {{operation}} |
| module @named_operands attributes { transform.with_named_sequence } { |
| |
| transform.named_sequence @foo(%arg0: !transform.any_op {transform.readonly}, |
| %arg1: !transform.any_value {transform.readonly}) -> () { |
| transform.debug.emit_remark_at %arg0, "operation" : !transform.any_op |
| transform.debug.emit_remark_at %arg1, "value" : !transform.any_value |
| transform.yield |
| } |
| |
| // expected-remark @below {{value}} |
| // expected-note @below {{value handle points to a block argument #0 in block #0 in region #0}} |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %0 = transform.test_produce_value_handle_to_self_operand %arg0 : (!transform.any_op) -> !transform.any_value |
| transform.include @foo failures(propagate) (%arg0, %0) : (!transform.any_op, !transform.any_value) -> () |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // expected-remark @below {{operation}} |
| module @named_return attributes { transform.with_named_sequence } { |
| |
| // expected-remark @below {{value}} |
| // expected-note @below {{value handle points to a block argument #0 in block #0 in region #0}} |
| transform.named_sequence @foo(%arg0: !transform.any_op {transform.readonly}) -> (!transform.any_op, !transform.any_value) { |
| %0 = transform.test_produce_value_handle_to_self_operand %arg0 : (!transform.any_op) -> !transform.any_value |
| transform.yield %arg0, %0 : !transform.any_op, !transform.any_value |
| } |
| |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %0:2 = transform.include @foo failures(propagate) (%arg0) : (!transform.any_op) -> (!transform.any_op, !transform.any_value) |
| transform.debug.emit_remark_at %0#0, "operation" : !transform.any_op |
| transform.debug.emit_remark_at %0#1, "value" : !transform.any_value |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes { transform.with_named_sequence } { |
| transform.named_sequence @match1(%current: !transform.any_op {transform.readonly}) -> (!transform.any_op) { |
| transform.test_succeed_if_operand_of_op_kind %current, "test.some_op" : !transform.any_op |
| transform.yield %current : !transform.any_op |
| } |
| |
| transform.named_sequence @match2(%current: !transform.any_op {transform.readonly}) -> (!transform.any_op) { |
| transform.test_succeed_if_operand_of_op_kind %current, "func.func" : !transform.any_op |
| transform.yield %current : !transform.any_op |
| } |
| |
| transform.named_sequence @action1(%current: !transform.any_op {transform.readonly}) { |
| transform.debug.emit_remark_at %current, "matched1" : !transform.any_op |
| transform.yield |
| } |
| transform.named_sequence @action2(%current: !transform.any_op {transform.readonly}) { |
| transform.debug.emit_remark_at %current, "matched2" : !transform.any_op |
| transform.yield |
| } |
| |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.foreach_match in %root |
| @match1 -> @action1, |
| @match2 -> @action2 |
| : (!transform.any_op) -> (!transform.any_op) |
| transform.yield |
| } |
| |
| // expected-remark @below {{matched2}} |
| func.func private @foo() |
| // expected-remark @below {{matched2}} |
| func.func private @bar() |
| "test.testtest"() : () -> () |
| // expected-remark @below {{matched1}} |
| "test.some_op"() : () -> () |
| } |
| |
| // ----- |
| |
| module attributes { transform.with_named_sequence } { |
| transform.named_sequence @match(!transform.any_op {transform.readonly}) |
| transform.named_sequence @action() |
| |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| // expected-error @below {{unresolved external symbol @match}} |
| transform.foreach_match in %root |
| @match -> @action : (!transform.any_op) -> !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes { transform.with_named_sequence } { |
| transform.named_sequence @match(%arg: !transform.any_op {transform.readonly}) { |
| transform.yield |
| } |
| transform.named_sequence @action() |
| |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| // expected-error @below {{unresolved external symbol @action}} |
| transform.foreach_match in %root |
| @match -> @action : (!transform.any_op) -> !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes { transform.with_named_sequence } { |
| transform.named_sequence @match(%arg: !transform.any_op {transform.readonly}) { |
| // expected-error @below {{expected operations in the match part to implement MatchOpInterface}} |
| "test.unknown_op"() : () -> () |
| transform.yield |
| } |
| transform.named_sequence @action() { |
| transform.yield |
| } |
| |
| transform.named_sequence @__transform_main(%root: !transform.any_op) { |
| transform.foreach_match in %root |
| @match -> @action : (!transform.any_op) -> !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes { transform.with_named_sequence } { |
| transform.named_sequence @match_func(%arg0: !transform.any_op {transform.readonly}) |
| -> !transform.any_op { |
| transform.match.operation_name %arg0 ["func.func"] : !transform.any_op |
| transform.yield %arg0 : !transform.any_op |
| } |
| |
| transform.named_sequence @print_func(%arg0: !transform.any_op {transform.readonly}) { |
| transform.debug.emit_remark_at %arg0, "matched func" : !transform.any_op |
| transform.yield |
| } |
| |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| transform.foreach_match in %arg0 @match_func -> @print_func : (!transform.any_op) -> !transform.any_op |
| transform.yield |
| } |
| |
| // expected-remark @below {{matched func}} |
| func.func @payload() { |
| return |
| } |
| |
| // expected-remark @below {{matched func}} |
| func.func private @declaration() |
| |
| "test.something_else"() : () -> () |
| } |
| |
| // ----- |
| |
| module attributes { transform.with_named_sequence } { |
| transform.named_sequence @eq_1(%arg0: !transform.any_op {transform.readonly}) |
| -> !transform.any_op { |
| transform.match.operation_name %arg0 ["func.func"] : !transform.any_op |
| %0 = transform.test_produce_param_with_number_of_test_ops %arg0 : !transform.any_op |
| %1 = transform.param.constant 1 : i32 -> !transform.test_dialect_param |
| transform.match.param.cmpi eq %0, %1 : !transform.test_dialect_param |
| transform.debug.emit_remark_at %arg0, "matched == 1" : !transform.any_op |
| transform.yield %arg0 : !transform.any_op |
| } |
| |
| transform.named_sequence @ne_0(%arg0: !transform.any_op {transform.readonly}) |
| -> !transform.any_op { |
| transform.match.operation_name %arg0 ["func.func"] : !transform.any_op |
| %0 = transform.test_produce_param_with_number_of_test_ops %arg0 : !transform.any_op |
| %1 = transform.param.constant 0 : i32 -> !transform.test_dialect_param |
| transform.match.param.cmpi ne %0, %1 : !transform.test_dialect_param |
| transform.debug.emit_remark_at %arg0, "matched != 0" : !transform.any_op |
| transform.yield %arg0 : !transform.any_op |
| } |
| |
| transform.named_sequence @gt_m1(%arg0: !transform.any_op {transform.readonly}) |
| -> !transform.any_op { |
| transform.match.operation_name %arg0 ["func.func"] : !transform.any_op |
| %0 = transform.test_produce_param_with_number_of_test_ops %arg0 : !transform.any_op |
| %1 = transform.param.constant -1 : i32 -> !transform.test_dialect_param |
| transform.match.param.cmpi gt %0, %1 : !transform.test_dialect_param |
| transform.debug.emit_remark_at %arg0, "matched > -1" : !transform.any_op |
| transform.yield %arg0 : !transform.any_op |
| } |
| |
| transform.named_sequence @ge_1(%arg0: !transform.any_op {transform.readonly}) |
| -> !transform.any_op { |
| transform.match.operation_name %arg0 ["func.func"] : !transform.any_op |
| %0 = transform.test_produce_param_with_number_of_test_ops %arg0 : !transform.any_op |
| %1 = transform.param.constant 1 : i32 -> !transform.test_dialect_param |
| transform.match.param.cmpi ge %0, %1 : !transform.test_dialect_param |
| transform.debug.emit_remark_at %arg0, "matched >= 1" : !transform.any_op |
| transform.yield %arg0 : !transform.any_op |
| } |
| |
| transform.named_sequence @lt_1(%arg0: !transform.any_op {transform.readonly}) |
| -> !transform.any_op { |
| transform.match.operation_name %arg0 ["func.func"] : !transform.any_op |
| %0 = transform.test_produce_param_with_number_of_test_ops %arg0 : !transform.any_op |
| %1 = transform.param.constant 1 : i32 -> !transform.test_dialect_param |
| transform.match.param.cmpi lt %0, %1 : !transform.test_dialect_param |
| transform.debug.emit_remark_at %arg0, "matched < 1" : !transform.any_op |
| transform.yield %arg0 : !transform.any_op |
| } |
| |
| transform.named_sequence @le_1(%arg0: !transform.any_op {transform.readonly}) |
| -> !transform.any_op { |
| transform.match.operation_name %arg0 ["func.func"] : !transform.any_op |
| %0 = transform.test_produce_param_with_number_of_test_ops %arg0 : !transform.any_op |
| %1 = transform.param.constant 1 : i32 -> !transform.test_dialect_param |
| transform.match.param.cmpi le %0, %1 : !transform.test_dialect_param |
| transform.debug.emit_remark_at %arg0, "matched <= 1" : !transform.any_op |
| transform.yield %arg0 : !transform.any_op |
| } |
| |
| transform.named_sequence @do_nothing(%arg0: !transform.any_op {transform.readonly}) { |
| transform.yield |
| } |
| |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %0 = transform.foreach_match in %arg0 @eq_1 -> @do_nothing : (!transform.any_op) -> !transform.any_op |
| %1 = transform.foreach_match in %0 @ne_0 -> @do_nothing : (!transform.any_op) -> !transform.any_op |
| %2 = transform.foreach_match in %1 @gt_m1 -> @do_nothing : (!transform.any_op) -> !transform.any_op |
| %3 = transform.foreach_match in %2 @ge_1 -> @do_nothing : (!transform.any_op) -> !transform.any_op |
| %4 = transform.foreach_match in %3 @lt_1 -> @do_nothing : (!transform.any_op) -> !transform.any_op |
| %5 = transform.foreach_match in %4 @le_1 -> @do_nothing : (!transform.any_op) -> !transform.any_op |
| transform.yield |
| } |
| |
| // expected-remark @below {{matched > -1}} |
| // expected-remark @below {{matched < 1}} |
| // expected-remark @below {{matched <= 1}} |
| func.func private @declaration() |
| |
| // expected-remark @below {{matched == 1}} |
| // expected-remark @below {{matched != 0}} |
| // expected-remark @below {{matched > -1}} |
| // expected-remark @below {{matched >= 1}} |
| // expected-remark @below {{matched <= 1}} |
| func.func @definition() { |
| "test.something"() : () -> () |
| return |
| } |
| } |
| |
| // ----- |
| |
| // CHECK-LABEL: func @test_tracked_rewrite() { |
| // CHECK-NEXT: transform.test_dummy_payload_op {new_op} : () -> i1 |
| // CHECK-NEXT: transform.test_dummy_payload_op {new_op} : () -> i1 |
| // CHECK-NEXT: return |
| // CHECK-NEXT: } |
| func.func @test_tracked_rewrite() { |
| %0 = transform.test_dummy_payload_op {replace_me} : () -> (i1) |
| %1 = transform.test_dummy_payload_op {erase_me} : () -> (i1) |
| %2 = transform.test_dummy_payload_op {replace_me} : () -> (i1) |
| func.return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %0 = transform.structured.match ops{["transform.test_dummy_payload_op"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| // expected-remark @below {{2 iterations}} |
| transform.test_tracked_rewrite %0 : (!transform.any_op) -> () |
| // One replacement op (test.drop_mapping) is dropped from the mapping. |
| %p = transform.num_associations %0 : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below {{2}} |
| transform.debug.emit_param_as_remark %p : !transform.param<i64> |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // Parameter deduplication happens by value |
| |
| module attributes {transform.with_named_sequence} { |
| |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %1 = transform.param.constant 1 -> !transform.param<i64> |
| %2 = transform.param.constant 1 -> !transform.param<i64> |
| %3 = transform.param.constant 2 -> !transform.param<i64> |
| %4 = transform.merge_handles %1, %2 { deduplicate } : !transform.param<i64> |
| %p = transform.num_associations %4 : (!transform.param<i64>) -> !transform.param<i64> |
| // expected-remark @below {{1}} |
| transform.debug.emit_param_as_remark %p : !transform.param<i64> |
| |
| %5 = transform.merge_handles %1, %1 { deduplicate } : !transform.param<i64> |
| %p2 = transform.num_associations %5 : (!transform.param<i64>) -> !transform.param<i64> |
| // expected-remark @below {{1}} |
| transform.debug.emit_param_as_remark %p2 : !transform.param<i64> |
| |
| %6 = transform.merge_handles %1, %3 { deduplicate } : !transform.param<i64> |
| %p3 = transform.num_associations %6 : (!transform.param<i64>) -> !transform.param<i64> |
| // expected-remark @below {{2}} |
| transform.debug.emit_param_as_remark %p3 : !transform.param<i64> |
| |
| %7 = transform.merge_handles %1, %1, %2, %3 : !transform.param<i64> |
| %p4 = transform.num_associations %7 : (!transform.param<i64>) -> !transform.param<i64> |
| // expected-remark @below {{4}} |
| transform.debug.emit_param_as_remark %p4 : !transform.param<i64> |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| %0:3 = "test.get_two_results"() : () -> (i32, i32, f32) |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %1 = transform.structured.match ops{["test.get_two_results"]} in %arg0 : (!transform.any_op) -> !transform.any_op |
| %2 = transform.test_produce_value_handle_to_result %1, 0 : (!transform.any_op) -> !transform.any_value |
| %3 = transform.test_produce_value_handle_to_result %1, 1 : (!transform.any_op) -> !transform.any_value |
| |
| %4 = transform.merge_handles %2, %2 { deduplicate } : !transform.any_value |
| %p = transform.num_associations %4 : (!transform.any_value) -> !transform.param<i64> |
| // expected-remark @below {{1}} |
| transform.debug.emit_param_as_remark %p : !transform.param<i64> |
| |
| %5 = transform.merge_handles %2, %3 { deduplicate } : !transform.any_value |
| %p2 = transform.num_associations %5 : (!transform.any_value) -> !transform.param<i64> |
| // expected-remark @below {{2}} |
| transform.debug.emit_param_as_remark %p2 : !transform.param<i64> |
| |
| %6 = transform.test_produce_value_handle_to_result %1, 0 : (!transform.any_op) -> !transform.any_value |
| %7 = transform.merge_handles %2, %6 { deduplicate } : !transform.any_value |
| %p3 = transform.num_associations %6 : (!transform.any_value) -> !transform.param<i64> |
| // expected-remark @below {{1}} |
| transform.debug.emit_param_as_remark %p3 : !transform.param<i64> |
| |
| %8 = transform.merge_handles %2, %2, %3, %4 : !transform.any_value |
| %p4 = transform.num_associations %8 : (!transform.any_value) -> !transform.param<i64> |
| // expected-remark @below {{4}} |
| transform.debug.emit_param_as_remark %p4 : !transform.param<i64> |
| transform.yield |
| } |
| } |
| // ----- |
| |
| // CHECK-LABEL: func @test_annotation() |
| // CHECK-NEXT: "test.annotate_me"() |
| // CHECK-SAME: any_attr = "example" |
| // CHECK-SAME: broadcast_attr = 2 : i64 |
| // CHECK-SAME: new_attr = 1 : i32 |
| // CHECK-SAME: unit_attr |
| // CHECK-NEXT: "test.annotate_me"() |
| // CHECK-SAME: any_attr = "example" |
| // CHECK-SAME: broadcast_attr = 2 : i64 |
| // CHECK-SAME: existing_attr = "test" |
| // CHECK-SAME: new_attr = 1 : i32 |
| // CHECK-SAME: unit_attr |
| // CHECK-NEXT: "test.annotate_me"() |
| // CHECK-SAME: any_attr = "example" |
| // CHECK-SAME: broadcast_attr = 2 : i64 |
| // CHECK-SAME: new_attr = 1 : i32 |
| // CHECK-SAME: unit_attr |
| func.func @test_annotation() { |
| %0 = "test.annotate_me"() : () -> (i1) |
| %1 = "test.annotate_me"() {existing_attr = "test"} : () -> (i1) |
| %2 = "test.annotate_me"() {new_attr = 0} : () -> (i1) |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %0 = transform.structured.match ops{["test.annotate_me"]} in %arg0 : (!transform.any_op) -> !transform.any_op |
| %1 = transform.test_produce_param_with_number_of_test_ops %0 : !transform.any_op |
| transform.annotate %0 "new_attr" = %1 : !transform.any_op, !transform.test_dialect_param |
| |
| %2 = transform.param.constant 2 -> !transform.param<i64> |
| transform.annotate %0 "broadcast_attr" = %2 : !transform.any_op, !transform.param<i64> |
| transform.annotate %0 "unit_attr" : !transform.any_op |
| |
| %3 = transform.param.constant "example" -> !transform.any_param |
| transform.annotate %0 "any_attr" = %3 : !transform.any_op, !transform.any_param |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @notify_payload_op_replaced(%arg0: index, %arg1: index) { |
| %0 = arith.muli %arg0, %arg1 {original} : index |
| // expected-remark @below{{updated handle}} |
| %1 = arith.muli %arg0, %arg1 {replacement} : index |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %0 = transform.structured.match attributes{original} in %arg1 : (!transform.any_op) -> !transform.any_op |
| %1 = transform.structured.match attributes{replacement} in %arg1 : (!transform.any_op) -> !transform.any_op |
| transform.test_notify_payload_op_replaced %0, %1 : (!transform.any_op, !transform.any_op) -> () |
| transform.debug.emit_remark_at %0, "updated handle" : !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // CHECK-LABEL: func @test_apply_cse() |
| // CHECK: %[[const:.*]] = arith.constant 0 : index |
| // CHECK: %[[ex1:.*]] = scf.execute_region -> index { |
| // CHECK: scf.yield %[[const]] |
| // CHECK: } |
| // CHECK: %[[ex2:.*]] = scf.execute_region -> index { |
| // CHECK: scf.yield %[[const]] |
| // CHECK: } |
| // CHECK: return %[[const]], %[[ex1]], %[[ex2]] |
| func.func @test_apply_cse() -> (index, index, index) { |
| // expected-remark @below{{eliminated 1}} |
| // expected-remark @below{{eliminated 2}} |
| %0 = arith.constant 0 : index |
| %1 = scf.execute_region -> index { |
| %2 = arith.constant 0 : index |
| scf.yield %2 : index |
| } {first} |
| %3 = scf.execute_region -> index { |
| %4 = arith.constant 0 : index |
| scf.yield %4 : index |
| } {second} |
| return %0, %1, %3 : index, index, index |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| %first = transform.structured.match attributes{first} in %0 : (!transform.any_op) -> !transform.any_op |
| %elim_first = transform.structured.match ops{["arith.constant"]} in %first : (!transform.any_op) -> !transform.any_op |
| %second = transform.structured.match attributes{first} in %0 : (!transform.any_op) -> !transform.any_op |
| %elim_second = transform.structured.match ops{["arith.constant"]} in %first : (!transform.any_op) -> !transform.any_op |
| |
| // There are 3 arith.constant ops. |
| %all = transform.structured.match ops{["arith.constant"]} in %0 : (!transform.any_op) -> !transform.any_op |
| %p = transform.num_associations %all : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below{{3}} |
| transform.debug.emit_param_as_remark %p : !transform.param<i64> |
| // "deduplicate" has no effect because these are 3 different ops. |
| %merged_before = transform.merge_handles deduplicate %all : !transform.any_op |
| %p2 = transform.num_associations %merged_before : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below{{3}} |
| transform.debug.emit_param_as_remark %p2 : !transform.param<i64> |
| |
| // Apply CSE. |
| transform.apply_cse to %0 : !transform.any_op |
| |
| // The handle is still mapped to 3 arith.constant ops. |
| %p3 = transform.num_associations %all : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below{{3}} |
| transform.debug.emit_param_as_remark %p3 : !transform.param<i64> |
| // But they are all the same op. |
| %merged_after = transform.merge_handles deduplicate %all : !transform.any_op |
| %p4 = transform.num_associations %merged_after : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below{{1}} |
| transform.debug.emit_param_as_remark %p4 : !transform.param<i64> |
| |
| // The other handles were also updated. |
| transform.debug.emit_remark_at %elim_first, "eliminated 1" : !transform.any_op |
| %p5 = transform.num_associations %elim_first : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below{{1}} |
| transform.debug.emit_param_as_remark %p5 : !transform.param<i64> |
| transform.debug.emit_remark_at %elim_second, "eliminated 2" : !transform.any_op |
| %p6 = transform.num_associations %elim_second : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below{{1}} |
| transform.debug.emit_param_as_remark %p6 : !transform.param<i64> |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // CHECK-LABEL: func @test_licm( |
| // CHECK: arith.muli |
| // CHECK: scf.for {{.*}} { |
| // CHECK: vector.print |
| // CHECK: } |
| func.func @test_licm(%arg0: index, %arg1: index, %arg2: index) { |
| scf.for %iv = %arg0 to %arg1 step %arg2 { |
| %0 = arith.muli %arg0, %arg1 : index |
| vector.print %0 : index |
| } |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %0 = transform.structured.match ops{["scf.for"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| transform.apply_licm to %0 : !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // expected-note @below{{when applied to this op}} |
| module attributes {transform.with_named_sequence} { |
| func.func @test_licm_invalid() { |
| return |
| } |
| |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| // expected-error @below{{transform applied to the wrong op kind}} |
| transform.apply_licm to %arg1 : !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @get_parent_op() { |
| // expected-remark @below{{found test.foo parent}} |
| "test.foo"() ({ |
| // expected-remark @below{{direct parent}} |
| "test.bar"() ({ |
| "test.qux"() : () -> () |
| "test.qux"() : () -> () |
| }) : () -> () |
| }) : () -> () |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg1: !transform.any_op) { |
| %0 = transform.structured.match ops{["test.qux"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| |
| // Get parent by name. |
| %1 = transform.get_parent_op %0 {op_name = "test.foo"} : (!transform.any_op) -> !transform.any_op |
| transform.debug.emit_remark_at %1, "found test.foo parent" : !transform.any_op |
| |
| // Get immediate parent. |
| %2 = transform.get_parent_op %0 : (!transform.any_op) -> !transform.any_op |
| transform.debug.emit_remark_at %2, "direct parent" : !transform.any_op |
| %p = transform.num_associations %2 : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below{{2}} |
| transform.debug.emit_param_as_remark %p : !transform.param<i64> |
| |
| // Deduplicate results. |
| %3 = transform.structured.match ops{["test.qux"]} in %arg1 : (!transform.any_op) -> !transform.any_op |
| %4 = transform.get_parent_op %3 {deduplicate} : (!transform.any_op) -> !transform.any_op |
| %p2 = transform.num_associations %4 : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below{{1}} |
| transform.debug.emit_param_as_remark %p2 : !transform.param<i64> |
| transform.yield |
| } |
| } |
| |
| |
| // ----- |
| |
| // expected-note @below {{target op}} |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // expected-error @below{{could not find a parent op that matches all requirements}} |
| %3 = transform.get_parent_op %arg0 {op_name = "builtin.module"} : (!transform.any_op) -> !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @cast(%arg0: f32) -> f64 { |
| // expected-remark @below{{f64}} |
| %0 = arith.extf %arg0 : f32 to f64 |
| return %0 : f64 |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %0 = transform.structured.match ops{["arith.extf"]} in %arg0 : (!transform.any_op) -> !transform.op<"arith.extf"> |
| %1 = transform.get_result %0[0] : (!transform.op<"arith.extf">) -> !transform.any_value |
| %2 = transform.get_type %1 : (!transform.any_value) -> !transform.type |
| transform.debug.emit_param_as_remark %2 at %0 : !transform.type, !transform.op<"arith.extf"> |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // expected-error @below {{expected type attribute, got 0 : i32}} |
| transform.test_produce_param (0 : i32) : !transform.type |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // expected-error @below {{expected affine map attribute, got 0 : i32}} |
| transform.test_produce_param (0 : i32) : !transform.affine_map |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // CHECK-LABEL: @type_param_anchor |
| func.func private @type_param_anchor() |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // CHECK: test_produce_param(f32) : !transform.type |
| transform.test_produce_param(f32) : !transform.type |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // CHECK-LABEL: @affine_map_param_anchor |
| func.func private @affine_map_param_anchor() |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // CHECK: test_produce_param(#{{.*}}) : !transform.affine_map |
| transform.test_produce_param(affine_map<(d0) -> ()>) : !transform.affine_map |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @verify_success(%arg0: f64) -> f64 { |
| return %arg0 : f64 |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %0 = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op |
| transform.verify %0 : !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // expected-error @below{{fail_to_verify is set}} |
| // expected-note @below{{payload op}} |
| func.func @verify_failure(%arg0: f64) -> f64 { |
| return %arg0 : f64 |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %0 = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op |
| transform.test_produce_invalid_ir %0 : !transform.any_op |
| // expected-error @below{{failed to verify payload op}} |
| transform.verify %0 : !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @select() { |
| // expected-remark @below{{found foo}} |
| "test.foo"() : () -> () |
| // expected-remark @below{{found bar}} |
| "test.bar"() : () -> () |
| // expected-remark @below{{found foo}} |
| "test.foo"() : () -> () |
| func.return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // Match all ops inside the function (including the function itself). |
| %func_op = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op |
| %0 = transform.structured.match in %func_op : (!transform.any_op) -> !transform.any_op |
| %p = transform.num_associations %0 : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below{{5}} |
| transform.debug.emit_param_as_remark %p : !transform.param<i64> |
| |
| // Select "test.foo". |
| %foo = transform.select "test.foo" in %0 : (!transform.any_op) -> !transform.any_op |
| transform.debug.emit_remark_at %foo, "found foo" : !transform.any_op |
| |
| // Select "test.bar". |
| %bar = transform.select "test.bar" in %0 : (!transform.any_op) -> !transform.any_op |
| transform.debug.emit_remark_at %bar, "found bar" : !transform.any_op |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| // CHECK-LABEL: func @apply_dce( |
| // CHECK-NEXT: memref.store |
| // CHECK-NEXT: return |
| func.func @apply_dce(%f: f32, %m: memref<5xf32>, %idx: index) { |
| // Two dead ops, interleaved with a non-dead op. |
| %0 = tensor.empty() : tensor<5xf32> |
| memref.store %f, %m[%idx] : memref<5xf32> |
| %1 = tensor.insert %f into %0[%idx] : tensor<5xf32> |
| return |
| } |
| |
| module attributes {transform.with_named_sequence} { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| %func_op = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op |
| %empty_op = transform.structured.match ops{["tensor.empty"]} in %func_op : (!transform.any_op) -> !transform.any_op |
| transform.apply_dce to %func_op : !transform.any_op |
| |
| %p = transform.num_associations %empty_op : (!transform.any_op) -> !transform.param<i64> |
| // expected-remark @below{{0}} |
| transform.debug.emit_param_as_remark %p : !transform.param<i64> |
| transform.yield |
| } |
| } |
| |
| |
| // ----- |
| |
| func.func @no_constant_under_loop(%lb: index, %ub: index, %step: index) { |
| scf.for %i= %lb to %ub step %step { |
| arith.constant 0 : index |
| } |
| return |
| } |
| |
| module @named_inclusion attributes { transform.with_named_sequence } { |
| // Match `arith.constant`s that are not nested under a `scf.for` and ensure |
| // there are none in the program |
| |
| transform.named_sequence @print(%root: !transform.any_op {transform.readonly}) { |
| transform.debug.emit_remark_at %root, "matched func" : !transform.any_op |
| transform.yield |
| } |
| |
| transform.named_sequence @match_constant_not_under_scf_for(%root: !transform.any_op {transform.readonly}) |
| -> !transform.any_op { |
| transform.match.operation_name %root ["arith.constant"] : !transform.any_op |
| %for = transform.get_parent_op %root { op_name = "scf.for", allow_empty_results } |
| : (!transform.any_op) -> (!transform.any_op) |
| transform.match.operation_empty %for : !transform.any_op |
| transform.yield %root : !transform.any_op |
| } |
| |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| transform.foreach_match in %arg0 |
| @match_constant_not_under_scf_for -> @print |
| : (!transform.any_op) -> (!transform.any_op) |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| func.func @no_constant_under_loop(%lb: index, %ub: index, %step: index) { |
| // expected-remark @below {{no parent scf.for}} |
| arith.constant 0 : index |
| return |
| } |
| |
| module @named_inclusion attributes { transform.with_named_sequence } { |
| // Match `arith.constant`s that are not nested under a `scf.for` and ensure |
| // there are none in the program |
| |
| transform.named_sequence @print(%root: !transform.any_op {transform.readonly}) { |
| transform.debug.emit_remark_at %root, "no parent scf.for" : !transform.any_op |
| transform.yield |
| } |
| |
| transform.named_sequence @match_constant_not_under_scf_for(%root: !transform.any_op {transform.readonly}) |
| -> !transform.any_op { |
| transform.match.operation_name %root ["arith.constant"] : !transform.any_op |
| %for = transform.get_parent_op %root { op_name = "scf.for", allow_empty_results } |
| : (!transform.any_op) -> (!transform.any_op) |
| transform.match.operation_empty %for : !transform.any_op |
| transform.yield %root : !transform.any_op |
| } |
| |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| transform.foreach_match in %arg0 |
| @match_constant_not_under_scf_for -> @print |
| : (!transform.any_op) -> (!transform.any_op) |
| transform.yield |
| } |
| } |
| |
| // ----- |
| |
| module attributes { transform.with_named_sequence } { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // expected-error @below {{result #0, associated with 2 payload objects, expected 1}} |
| transform.collect_matching @matcher in %arg0 : (!transform.any_op) -> !transform.any_op |
| transform.yield |
| } |
| |
| transform.named_sequence @matcher(%arg0: !transform.any_op {transform.readonly}) -> !transform.any_op { |
| %0 = transform.merge_handles %arg0, %arg0 : !transform.any_op |
| transform.yield %0 : !transform.any_op |
| } |
| } |
| |
| // ----- |
| |
| module attributes { transform.with_named_sequence } { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // expected-error @below {{unresolved external symbol @matcher}} |
| transform.collect_matching @matcher in %arg0 : (!transform.any_op) -> !transform.any_op |
| transform.yield |
| } |
| |
| transform.named_sequence @matcher(%arg0: !transform.any_op {transform.readonly}) -> !transform.any_op |
| } |
| |
| // ----- |
| |
| module attributes { transform.with_named_sequence } { |
| transform.named_sequence @__transform_main(%arg0: !transform.any_op) { |
| // expected-remark @below {{matched}} |
| %0 = transform.collect_matching @matcher in %arg0 : (!transform.any_op) -> !transform.any_op |
| // expected-remark @below {{matched}} |
| transform.debug.emit_remark_at %0, "matched" : !transform.any_op |
| transform.yield |
| } |
| |
| transform.named_sequence @matcher(%arg0: !transform.any_op {transform.readonly}) -> !transform.any_op { |
| transform.match.operation_name %arg0 ["transform.debug.emit_remark_at", "transform.collect_matching"] : !transform.any_op |
| transform.yield %arg0 : !transform.any_op |
| } |
| } |