These are considered noops.
Buferization will still fail on scf.execute_region which yield values.
This is used to make comprehensive bufferization interoperate better with external clients.
Differential Revision: https://reviews.llvm.org/D111130
// Cannot create IR past a yieldOp.
b.setInsertionPoint(yieldOp);
+ if (auto execOp = dyn_cast<scf::ExecuteRegionOp>(yieldOp->getParentOp())) {
+ if (execOp->getNumResults() != 0)
+ return execOp->emitError(
+ "expected result-less scf.execute_region containing op");
+ return success();
+ }
+
scf::ForOp forOp = dyn_cast<scf::ForOp>(yieldOp->getParentOp());
- assert(forOp && "only support scf::ForOp parent for scf::YieldOp");
+ if (!forOp)
+ return yieldOp->emitError("expected scf::ForOp parent for scf::YieldOp");
for (OpOperand &operand : yieldOp->getOpOperands()) {
auto tensorType = operand.get().getType().dyn_cast<TensorType>();
if (!tensorType)
%r = linalg.fill(%f0, %t) : f32, tensor<10x20xf32> -> tensor<10x20xf32>
return %r : tensor<10x20xf32>
}
+
+// -----
+
+func @main() -> tensor<4xi32> {
+ // expected-error @+1 {{unsupported op with tensors}}
+ %r = scf.execute_region -> tensor<4xi32> {
+ %A = constant dense<[1, 2, 3, 4]> : tensor<4xi32>
+ scf.yield %A: tensor<4xi32>
+ }
+ return %r: tensor<4xi32>
+}
+
+// -----
+
+func @main() -> i32 {
+ %c0 = constant 0: index
+ // expected-error @+1 {{expected result-less scf.execute_region containing op}}
+ %r = scf.execute_region -> i32 {
+ %A = constant dense<[1, 2, 3, 4]> : tensor<4xi32>
+ %e = tensor.extract %A[%c0]: tensor<4xi32>
+ scf.yield %e: i32
+ }
+ return %r: i32
+}
// CHECK: #[[$DYN_1D_MAP:.*]] = affine_map<(d0)[s0, s1] -> (d0 * s1 + s0)>
+// CHECK: memref.global "private" constant @__constant_4xi32 : memref<4xi32> = dense<[1, 2, 3, 4]>
+// CHECK: func private @some_external_func_within_scf_execute(memref<4xi32, #[[$DYN_1D_MAP]]>)
+func private @some_external_func_within_scf_execute(tensor<4xi32>)
+
+// CHECK: func @main()
+func @main() {
+// CHECK: %[[A:.*]] = memref.get_global @__constant_4xi32 : memref<4xi32>
+ %A = constant dense<[1, 2, 3, 4]> : tensor<4xi32>
+
+// CHECK: %[[B:.*]] = memref.cast %[[A]] : memref<4xi32> to memref<4xi32, #[[$DYN_1D_MAP]]>
+// CHECK: call @some_external_func_within_scf_execute(%[[B]]) : (memref<4xi32, #[[$DYN_1D_MAP]]>) -> ()
+ scf.execute_region {
+ call @some_external_func_within_scf_execute(%A) : (tensor<4xi32>) -> ()
+ scf.yield
+ }
+
+ return
+}
+
+// -----
+
+// CHECK: #[[$DYN_1D_MAP:.*]] = affine_map<(d0)[s0, s1] -> (d0 * s1 + s0)>
+
// CHECK: func private @some_external_func(memref<?xf32, #[[$DYN_1D_MAP]]>)
func private @some_external_func(tensor<?xf32>)