summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mlir/lib/Dialect/SPIRV/SPIRVDialect.cpp11
-rw-r--r--mlir/test/Dialect/SPIRV/Transforms/inlining.mlir45
2 files changed, 56 insertions, 0 deletions
diff --git a/mlir/lib/Dialect/SPIRV/SPIRVDialect.cpp b/mlir/lib/Dialect/SPIRV/SPIRVDialect.cpp
index 1460cf091eb..c99e7ca8b20 100644
--- a/mlir/lib/Dialect/SPIRV/SPIRVDialect.cpp
+++ b/mlir/lib/Dialect/SPIRV/SPIRVDialect.cpp
@@ -56,6 +56,17 @@ struct SPIRVInlinerInterface : public DialectInlinerInterface {
/// Returns true if the given region 'src' can be inlined into the region
/// 'dest' that is attached to an operation registered to the current dialect.
+ bool isLegalToInline(Region *dest, Region *src,
+ BlockAndValueMapping &) const final {
+ // Return true here when inlining into spv.selection and spv.loop
+ // operations.
+ auto op = dest->getParentOp();
+ return isa<spirv::SelectionOp>(op) || isa<spirv::LoopOp>(op);
+ }
+
+ /// Returns true if the given operation 'op', that is registered to this
+ /// dialect, can be inlined into the region 'dest' that is attached to an
+ /// operation registered to the current dialect.
bool isLegalToInline(Operation *op, Region *dest,
BlockAndValueMapping &) const final {
// TODO(antiagainst): Enable inlining structured control flows with return.
diff --git a/mlir/test/Dialect/SPIRV/Transforms/inlining.mlir b/mlir/test/Dialect/SPIRV/Transforms/inlining.mlir
index 9837d7babb7..75360194d7b 100644
--- a/mlir/test/Dialect/SPIRV/Transforms/inlining.mlir
+++ b/mlir/test/Dialect/SPIRV/Transforms/inlining.mlir
@@ -180,3 +180,48 @@ spv.module "Logical" "GLSL450" {
spv.Return
}
}
+
+// -----
+
+spv.module "Logical" "GLSL450" {
+ spv.globalVariable @arg_0 bind(0, 0) : !spv.ptr<!spv.struct<i32 [0]>, StorageBuffer>
+ spv.globalVariable @arg_1 bind(0, 1) : !spv.ptr<!spv.struct<i32 [0]>, StorageBuffer>
+ // CHECK: func @inline_into_selection_region
+ func @inline_into_selection_region() {
+ %1 = spv.constant 0 : i32
+ // CHECK-DAG: [[ADDRESS_ARG0:%.*]] = spv._address_of @arg_0
+ // CHECK-DAG: [[ADDRESS_ARG1:%.*]] = spv._address_of @arg_1
+ // CHECK-DAG: [[LOADPTR:%.*]] = spv.AccessChain [[ADDRESS_ARG0]]
+ // CHECK: [[VAL:%.*]] = spv.Load "StorageBuffer" [[LOADPTR]]
+ %2 = spv._address_of @arg_0 : !spv.ptr<!spv.struct<i32 [0]>, StorageBuffer>
+ %3 = spv._address_of @arg_1 : !spv.ptr<!spv.struct<i32 [0]>, StorageBuffer>
+ %4 = spv.AccessChain %2[%1] : !spv.ptr<!spv.struct<i32 [0]>, StorageBuffer>
+ %5 = spv.Load "StorageBuffer" %4 : i32
+ %6 = spv.SGreaterThan %5, %1 : i32
+ // CHECK: spv.selection
+ spv.selection {
+ spv.BranchConditional %6, ^bb1, ^bb2
+ ^bb1: // pred: ^bb0
+ // CHECK: [[STOREPTR:%.*]] = spv.AccessChain [[ADDRESS_ARG1]]
+ %7 = spv.AccessChain %3[%1] : !spv.ptr<!spv.struct<i32 [0]>, StorageBuffer>
+ // CHECK-NOT: spv.FunctionCall
+ // CHECK: spv.AtomicIAdd "Device" "AcquireRelease" [[STOREPTR]], [[VAL]]
+ // CHECK: spv.Branch
+ spv.FunctionCall @atomic_add(%5, %7) : (i32, !spv.ptr<i32, StorageBuffer>) -> ()
+ spv.Branch ^bb2
+ ^bb2 : // 2 preds: ^bb0, ^bb1
+ spv._merge
+ }
+ // CHECK: spv.Return
+ spv.Return
+ }
+ func @atomic_add(%arg0: i32, %arg1: !spv.ptr<i32, StorageBuffer>) {
+ %0 = spv.AtomicIAdd "Device" "AcquireRelease" %arg1, %arg0 : !spv.ptr<i32, StorageBuffer>
+ spv.Return
+ }
+ spv.EntryPoint "GLCompute" @inline_into_selection_region
+ spv.ExecutionMode @inline_into_selection_region "LocalSize", 32, 1, 1
+} attributes {capabilities = ["Shader"], extensions = ["SPV_KHR_storage_buffer_storage_class"]}
+
+// TODO: Add tests for inlining structured control flow into
+// structured control flow. \ No newline at end of file
OpenPOWER on IntegriCloud