diff --git a/mlir/include/mlir/Dialect/Transform/IR/TransformOps.td b/mlir/include/mlir/Dialect/Transform/IR/TransformOps.td --- a/mlir/include/mlir/Dialect/Transform/IR/TransformOps.td +++ b/mlir/include/mlir/Dialect/Transform/IR/TransformOps.td @@ -201,7 +201,7 @@ OptionalAttr:$illegal_ops, OptionalAttr:$legal_dialects, OptionalAttr:$illegal_dialects, - UnitAttr:$partialConversion); + UnitAttr:$partial_conversion); let results = (outs); let regions = (region MaxSizedRegion<1>:$patterns, diff --git a/mlir/test/Dialect/Transform/test-pattern-application.mlir b/mlir/test/Dialect/Transform/test-pattern-application.mlir --- a/mlir/test/Dialect/Transform/test-pattern-application.mlir +++ b/mlir/test/Dialect/Transform/test-pattern-application.mlir @@ -250,13 +250,63 @@ transform.apply_conversion_patterns.transform.test_conversion_patterns } with type_converter { transform.apply_conversion_patterns.transform.test_type_converter - } {illegal_ops = ["test.foo"], - legal_ops = ["func.func", "func.return", "test.new_op"]} + } {legal_ops = ["func.func", "func.return", "test.new_op"]} + : !transform.any_op +} + +// ----- + +// Full dialect conversion fails because test.bar is not replaced and not legal. + +// expected-note @below{{target op}} +func.func @full_dialect_conversion_failed() -> tensor<5xf32> { + %0 = "test.foo"() {replace_with_new_op = "test.bar"} : () -> (tensor<5xf32>) + // expected-error @below{{failed to legalize operation 'test.bar'}} + "test.bar"() : () -> () + return %0 : tensor<5xf32> +} + +transform.sequence failures(propagate) { +^bb1(%arg1: !transform.any_op): + %0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op + // expected-error @below{{dialect conversion failed}} + transform.apply_conversion_patterns to %0 { + transform.apply_conversion_patterns.transform.test_conversion_patterns + } with type_converter { + transform.apply_conversion_patterns.transform.test_type_converter + } {legal_ops = ["func.func", "func.return", "test.new_op"]} : !transform.any_op } // ----- +// Partial dialect conversion succeeds because test.bar is not explicitly +// illegal. + +// CHECK-LABEL: func @partial_dialect_conversion +// CHECK-NEXT: %[[m:.*]] = "test.new_op"() : () -> memref<5xf32> +// CHECK-NEXT: %[[cast:.*]] = builtin.unrealized_conversion_cast %0 : memref<5xf32> to tensor<5xf32> +// CHECK-NEXT: "test.bar" +// CHECK-NEXT: return %[[cast]] +func.func @partial_dialect_conversion() -> tensor<5xf32> { + %0 = "test.foo"() {replace_with_new_op = "test.bar"} : () -> (tensor<5xf32>) + "test.bar"() : () -> () + return %0 : tensor<5xf32> +} + +transform.sequence failures(propagate) { +^bb1(%arg1: !transform.any_op): + %0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op + transform.apply_conversion_patterns to %0 { + transform.apply_conversion_patterns.transform.test_conversion_patterns + } with type_converter { + transform.apply_conversion_patterns.transform.test_type_converter + } {legal_ops = ["func.func", "func.return", "test.new_op"], + partial_conversion} : !transform.any_op +} + +// ----- + transform.sequence failures(propagate) { ^bb1(%arg1: !transform.any_op): %0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op