[mlir][EDSC] Fix off-by-one BlockBuilder insertion point.
authorNicolas Vasilache <ntv@google.com>
Mon, 4 May 2020 20:36:47 +0000 (16:36 -0400)
committerNicolas Vasilache <ntv@google.com>
Tue, 5 May 2020 01:07:48 +0000 (21:07 -0400)
Summary:
In the particular case of an insertion in a block without a terminator, the BlockBuilder insertion point should be block->end().

Adding a unit test to exercise this.

Differential Revision: https://reviews.llvm.org/D79363

mlir/include/mlir/EDSC/Builders.h
mlir/test/EDSC/builder-api-test.cpp

index 7e0fbb7..c143789 100644 (file)
@@ -118,10 +118,9 @@ protected:
   /// As a consequence we must allocate a new OpBuilder + ScopedContext and
   /// let the escape.
   void enter(mlir::Block *block) {
-    bodyScope = new ScopedContext(
-        ScopedContext::getBuilderRef(),
-        OpBuilder::InsertPoint(block, std::prev(block->end())),
-        ScopedContext::getLocation());
+    bodyScope = new ScopedContext(ScopedContext::getBuilderRef(),
+                                  OpBuilder::InsertPoint(block, block->end()),
+                                  ScopedContext::getLocation());
     if (!block->empty()) {
       auto &termOp = block->back();
       if (termOp.isKnownTerminator())
index 6499451..cca6c20 100644 (file)
@@ -175,6 +175,33 @@ TEST_FUNC(builder_max_min_for) {
   f.erase();
 }
 
+TEST_FUNC(builder_block_append) {
+  using namespace edsc::op;
+  auto f = makeFunction("builder_blocks");
+
+  OpBuilder builder(f.getBody());
+  ScopedContext scope(builder, f.getLoc());
+
+  BlockHandle b1, functionBlock(&f.front());
+  BlockBuilder(&b1, {}, {})([&] { std_constant_index(0); });
+  BlockBuilder(b1, Append())([&] { std_constant_index(1); });
+  BlockBuilder(b1, Append())([&] { std_ret(); });
+  // Get back to entry block and add a branch into b1
+  BlockBuilder(functionBlock, Append())([&] { std_br(b1, {}); });
+
+  // clang-format off
+  // CHECK-LABEL: @builder_blocks
+  // CHECK-NEXT:   br ^bb1
+  // CHECK-NEXT: ^bb1: // pred: ^bb0
+  // CHECK-NEXT:   constant 0 : index
+  // CHECK-NEXT:   constant 1 : index
+  // CHECK-NEXT:   return
+  // CHECK-NEXT: }
+  // clang-format on
+  f.print(llvm::outs());
+  f.erase();
+}
+
 TEST_FUNC(builder_blocks) {
   using namespace edsc::op;
   auto f = makeFunction("builder_blocks");
@@ -1071,8 +1098,8 @@ TEST_FUNC(builder_loop_for_yield) {
   // CHECK:     [[sum:%[0-9]+]] = addf [[arg0]], [[arg1]] : f32
   // CHECK:     loop.yield [[arg1]], [[sum]] : f32, f32
   // CHECK:     addf [[res]]#0, [[res]]#1 : f32
-
   // clang-format on
+
   f.print(llvm::outs());
   f.erase();
 }