[llvm-branch-commits] [mlir] 43f34f5 - Added check if there are regions that do not implement the RegionBranchOpInterface.

Julian Gross via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Jan 20 03:27:32 PST 2021


Author: Julian Gross
Date: 2021-01-20T12:15:28+01:00
New Revision: 43f34f58349ae178fd1c95d6a73c6858f35f2ea1

URL: https://github.com/llvm/llvm-project/commit/43f34f58349ae178fd1c95d6a73c6858f35f2ea1
DIFF: https://github.com/llvm/llvm-project/commit/43f34f58349ae178fd1c95d6a73c6858f35f2ea1.diff

LOG: Added check if there are regions that do not implement the RegionBranchOpInterface.

Add a check if regions do not implement the RegionBranchOpInterface. This is not
allowed in the current deallocation steps. Furthermore, we handle edge-cases,
where a single region is attached and the parent operation has no results.

This fixes: https://bugs.llvm.org/show_bug.cgi?id=48575

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

Added: 
    

Modified: 
    mlir/lib/Transforms/BufferDeallocation.cpp
    mlir/test/Transforms/buffer-deallocation.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/lib/Transforms/BufferDeallocation.cpp b/mlir/lib/Transforms/BufferDeallocation.cpp
index bdd8515bdc05..a4155695fdf7 100644
--- a/mlir/lib/Transforms/BufferDeallocation.cpp
+++ b/mlir/lib/Transforms/BufferDeallocation.cpp
@@ -76,6 +76,31 @@ static void walkReturnOperations(Region *region, const FuncT &func) {
     }
 }
 
+/// Checks if all operations in a given region have at least one attached region
+/// that implements the RegionBranchOpInterface. This is not required in edge
+/// cases, where we have a single attached region and the parent operation has
+/// no results.
+static bool validateSupportedControlFlow(Region &region) {
+  bool success = true;
+  region.walk([&success](Operation *operation) {
+    auto regions = operation->getRegions();
+    // Walk over all operations in a region and check if the operation has at
+    // least one region and implements the RegionBranchOpInterface. If there
+    // is an operation that does not fulfill this condition, we cannot apply
+    // the deallocation steps. Furthermore, we accept cases, where we have a
+    // region that returns no results, since, in that case, the intra-region
+    // control flow does not affect the transformation.
+    size_t size = regions.size();
+    if (((size == 1 && !operation->getResults().empty()) || size > 1) &&
+        !dyn_cast<RegionBranchOpInterface>(operation)) {
+      operation->emitError("All operations with attached regions need to "
+                           "implement the RegionBranchOpInterface.");
+      success = false;
+    }
+  });
+  return success;
+}
+
 namespace {
 
 //===----------------------------------------------------------------------===//
@@ -506,7 +531,12 @@ struct BufferDeallocationPass : BufferDeallocationBase<BufferDeallocationPass> {
     if (backedges.size()) {
       getFunction().emitError(
           "Structured control-flow loops are supported only.");
-      return;
+      return signalPassFailure();
+    }
+
+    // Check that the control flow structures are supported.
+    if (!validateSupportedControlFlow(getFunction().getRegion())) {
+      return signalPassFailure();
     }
 
     // Place all required temporary alloc, copy and dealloc nodes.

diff  --git a/mlir/test/Transforms/buffer-deallocation.mlir b/mlir/test/Transforms/buffer-deallocation.mlir
index f61d501dff9c..90b39b202fb0 100644
--- a/mlir/test/Transforms/buffer-deallocation.mlir
+++ b/mlir/test/Transforms/buffer-deallocation.mlir
@@ -1,4 +1,4 @@
-// RUN: mlir-opt -buffer-deallocation -split-input-file %s | FileCheck %s
+// RUN: mlir-opt -verify-diagnostics -buffer-deallocation -split-input-file %s | FileCheck %s
 
 // This file checks the behaviour of BufferDeallocation pass for moving and
 // inserting missing DeallocOps in their correct positions. Furthermore,
@@ -1094,7 +1094,7 @@ func @loop_nested_alloc(
 // The BufferDeallocation transformation should fail on this explicit
 // control-flow loop since they are not supported.
 
-// CHECK-LABEL: func @loop_dynalloc
+// expected-error at +1 {{Structured control-flow loops are supported only}}
 func @loop_dynalloc(
   %arg0 : i32,
   %arg1 : i32,
@@ -1121,15 +1121,13 @@ func @loop_dynalloc(
   return
 }
 
-// expected-error at +1 {{Structured control-flow loops are supported only}}
-
 // -----
 
 // Test Case: explicit control-flow loop with a dynamically allocated buffer.
 // The BufferDeallocation transformation should fail on this explicit
 // control-flow loop since they are not supported.
 
-// CHECK-LABEL: func @do_loop_alloc
+// expected-error at +1 {{Structured control-flow loops are supported only}}
 func @do_loop_alloc(
   %arg0 : i32,
   %arg1 : i32,
@@ -1155,8 +1153,6 @@ func @do_loop_alloc(
   return
 }
 
-// expected-error at +1 {{Structured control-flow loops are supported only}}
-
 // -----
 
 // CHECK-LABEL: func @assumingOp(
@@ -1193,3 +1189,20 @@ func @assumingOp(
 // CHECK-NEXT:    shape.assuming_yield %[[RETURNING_ALLOC]]
 //      CHECK: test.copy(%[[ASSUMING_RESULT:.*]], %[[ARG2]])
 // CHECK-NEXT: dealloc %[[ASSUMING_RESULT]]
+
+// -----
+
+// Test Case: The op "test.bar" does not implement the RegionBranchOpInterface.
+// This is not allowed in buffer deallocation.
+
+func @noRegionBranchOpInterface() {
+// expected-error at +1 {{All operations with attached regions need to implement the RegionBranchOpInterface.}}
+  %0 = "test.bar"() ( {
+// expected-error at +1 {{All operations with attached regions need to implement the RegionBranchOpInterface.}}
+    %1 = "test.bar"() ( {
+      "test.yield"() : () -> ()
+    }) : () -> (i32)
+    "test.yield"() : () -> ()
+  }) : () -> (i32)
+  "test.terminator"() : () -> ()
+}


        


More information about the llvm-branch-commits mailing list