diff --git a/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h b/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h --- a/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h +++ b/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h @@ -527,9 +527,10 @@ } /// Returns the single block of the given region. - Block *getBodyBlock(unsigned region = 0) { - return &this->getOperation()->getRegion(region).front(); - } + Block *getBodyBlock(unsigned regionIndex = 0) { + auto ®ion = this->getOperation()->getRegion(regionIndex); + return region.empty() ? nullptr : ®ion.front(); + } /// Sets up the mapping between the entry block of the given region of this op /// and the relevant list of Payload IR operations in the given state. The diff --git a/mlir/lib/Dialect/Transform/IR/TransformOps.cpp b/mlir/lib/Dialect/Transform/IR/TransformOps.cpp --- a/mlir/lib/Dialect/Transform/IR/TransformOps.cpp +++ b/mlir/lib/Dialect/Transform/IR/TransformOps.cpp @@ -755,6 +755,10 @@ return; } + // Early exit on empty region. + if (!getBodyBlock()) + return; + // Carry over all effects on the argument of the entry block as those on the // operand, this is the same value just remapped. for (Operation &op : *getBodyBlock()) { diff --git a/mlir/test/IR/visitors.mlir b/mlir/test/IR/visitors.mlir --- a/mlir/test/IR/visitors.mlir +++ b/mlir/test/IR/visitors.mlir @@ -210,3 +210,62 @@ // CHECK: Erasing block ^bb0 from region 0 from operation 'regionOp0' // CHECK: Erasing block ^bb0 from region 0 from operation 'func.func' // CHECK: Erasing block ^bb0 from region 0 from operation 'builtin.module' + +// ----- + +transform.sequence failures(propagate) { +^bb0(%arg0: !pdl.operation): + sequence %arg0 : !pdl.operation failures(propagate) { + ^bb0(%arg1: !pdl.operation): + } +} + +// CHECK-LABEL: Op pre-order visits +// CHECK: Visiting op 'builtin.module' +// CHECK: Visiting op 'transform.sequence' +// CHECK: Visiting op 'transform.sequence' +// CHECK: Visiting op 'transform.yield' +// CHECK: Visiting op 'transform.yield' +// CHECK-LABEL:Block pre-order visits +// CHECK: Visiting block ^bb0 from region 0 from operation 'builtin.module' +// CHECK: Visiting block ^bb0 from region 0 from operation 'transform.sequence' +// CHECK: Visiting block ^bb0 from region 0 from operation 'transform.sequence' +// CHECK-LABEL:Region pre-order visits +// CHECK: Visiting region 0 from operation 'builtin.module' +// CHECK: Visiting region 0 from operation 'transform.sequence' +// CHECK: Visiting region 0 from operation 'transform.sequence' +// CHECK-LABEL:Op post-order visits +// CHECK: Visiting op 'transform.yield' +// CHECK: Visiting op 'transform.sequence' +// CHECK: Visiting op 'transform.yield' +// CHECK: Visiting op 'transform.sequence' +// CHECK: Visiting op 'builtin.module' +// CHECK-LABEL:Block post-order visits +// CHECK: Visiting block ^bb0 from region 0 from operation 'transform.sequence' +// CHECK: Visiting block ^bb0 from region 0 from operation 'transform.sequence' +// CHECK: Visiting block ^bb0 from region 0 from operation 'builtin.module' +// CHECK-LABEL:Region post-order visits +// CHECK: Visiting region 0 from operation 'transform.sequence' +// CHECK: Visiting region 0 from operation 'transform.sequence' +// CHECK: Visiting region 0 from operation 'builtin.module' +// CHECK-LABEL:Op pre-order erasures (skip) +// CHECK: Erasing op 'transform.sequence' +// CHECK: Erasing op 'transform.yield' +// CHECK-LABEL:Block pre-order erasures (skip) +// CHECK: Erasing block ^bb0 from region 0 from operation 'transform.sequence' +// CHECK-LABEL:Op post-order erasures (skip) +// CHECK: Erasing op 'transform.yield' +// CHECK: Erasing op 'transform.sequence' +// CHECK: Erasing op 'transform.yield' +// CHECK-LABEL:Block post-order erasures (skip) +// CHECK: Erasing block ^bb0 from region 0 from operation 'transform.sequence' +// CHECK-LABEL:Op post-order erasures (no skip) +// CHECK: Erasing op 'transform.yield' +// CHECK: Erasing op 'transform.sequence' +// CHECK: Erasing op 'transform.yield' +// CHECK: Erasing op 'transform.sequence' +// CHECK: Erasing op 'builtin.module' +// CHECK-LABEL:Block post-order erasures (no skip) +// CHECK: Erasing block ^bb0 from region 0 from operation 'transform.sequence' +// CHECK: Erasing block ^bb0 from region 0 from operation 'transform.sequence' +// CHECK: Erasing block ^bb0 from region 0 from operation 'builtin.module'