1// RUN: mlir-opt %s --split-input-file --verify-diagnostics \ 2// RUN: --transform-interpreter 3 4func.func private @bar() 5 6func.func @foo() { 7 %c0 = arith.constant 0 : index 8 %c1 = arith.constant 1 : index 9 %c10 = arith.constant 10 : index 10 // expected-note @below {{ancestor payload op}} 11 scf.for %i = %c0 to %c1 step %c10 { 12 // expected-note @below {{descendant payload op}} 13 scf.for %j = %c0 to %c1 step %c10 { 14 func.call @bar() : () -> () 15 } 16 } 17 return 18} 19 20module attributes {transform.with_named_sequence} { 21 transform.named_sequence @__transform_main(%arg0: !transform.any_op) { 22 %0 = transform.structured.match ops{["scf.for"]} in %arg0 : (!transform.any_op) -> !transform.op<"scf.for"> 23 %1 = transform.test_reverse_payload_ops %0 : (!transform.op<"scf.for">) -> !transform.op<"scf.for"> 24 // expected-error @below {{transform operation consumes a handle pointing to an ancestor payload operation before its descendant}} 25 // expected-note @below {{the ancestor is likely erased or rewritten before the descendant is accessed, leading to undefined behavior}} 26 transform.test_consume_operand_each %1 : !transform.op<"scf.for"> 27 transform.yield 28 } 29} 30 31// ----- 32 33func.func private @bar() 34 35func.func @foo() { 36 %c0 = arith.constant 0 : index 37 %c1 = arith.constant 1 : index 38 %c10 = arith.constant 10 : index 39 scf.for %i = %c0 to %c1 step %c10 { 40 scf.for %j = %c0 to %c1 step %c10 { 41 func.call @bar() : () -> () 42 } 43 } 44 return 45} 46 47// No error here, processing ancestors before descendants. 48module attributes {transform.with_named_sequence} { 49 transform.named_sequence @__transform_main(%arg0: !transform.any_op) { 50 %0 = transform.structured.match ops{["scf.for"]} in %arg0 : (!transform.any_op) -> !transform.op<"scf.for"> 51 transform.test_consume_operand_each %0 : !transform.op<"scf.for"> 52 transform.yield 53 } 54} 55