let hasFolder = 1;
}
-def Shape_YieldOp : Shape_Op<"yield", [NoSideEffect, Terminator]> {
+def Shape_YieldOp : Shape_Op<"yield",
+ [HasParent<"ReduceOp">,
+ NoSideEffect,
+ ReturnLike,
+ Terminator]> {
let summary = "Returns the value to parent op";
let arguments = (ins Variadic<AnyType>:$operands);
"OpBuilder &b, OperationState &result", [{ build(b, result, llvm::None); }]
>];
+ let verifier = [{ return ::verify(*this); }];
let assemblyFormat = "attr-dict ($operands^ `:` type($operands))?";
}
}
//===----------------------------------------------------------------------===//
+// YieldOp
+//===----------------------------------------------------------------------===//
+
+static LogicalResult verify(YieldOp op) {
+ auto *parentOp = op.getParentOp();
+ auto results = parentOp->getResults();
+ auto operands = op.getOperands();
+
+ if (parentOp->getNumResults() != op.getNumOperands())
+ return op.emitOpError() << "number of operands does not match number of "
+ "results of its parent";
+ for (auto e : llvm::zip(results, operands))
+ if (std::get<0>(e).getType() != std::get<1>(e).getType())
+ return op.emitOpError()
+ << "types mismatch between yield op and its parent";
+
+ return success();
+}
+
+//===----------------------------------------------------------------------===//
// SplitAtOp
//===----------------------------------------------------------------------===//
// expected-error@+1 {{ReduceOp body is expected to have 3 arguments}}
%num_elements = shape.reduce(%shape, %init) -> !shape.size {
^bb0(%index: index, %dim: !shape.size):
- "shape.yield"(%dim) : (!shape.size) -> ()
+ shape.yield %dim : !shape.size
}
}
func @reduce_op_arg0_wrong_type(%shape : !shape.shape, %init : !shape.size) {
// expected-error@+1 {{argument 0 of ReduceOp body is expected to be of IndexType}}
%num_elements = shape.reduce(%shape, %init) -> !shape.size {
- ^bb0(%index: f32, %dim: !shape.size, %lci: !shape.size):
- %acc = "shape.add"(%lci, %dim) : (!shape.size, !shape.size) -> !shape.size
- "shape.yield"(%acc) : (!shape.size) -> ()
+ ^bb0(%index: f32, %dim: !shape.size, %acc: !shape.size):
+ %new_acc = "shape.add"(%acc, %dim)
+ : (!shape.size, !shape.size) -> !shape.size
+ shape.yield %new_acc : !shape.size
}
}
// expected-error@+1 {{argument 1 of ReduceOp body is expected to be of SizeType}}
%num_elements = shape.reduce(%shape, %init) -> !shape.size {
^bb0(%index: index, %dim: f32, %lci: !shape.size):
- "shape.yield"() : () -> ()
+ shape.yield
}
}
// expected-error@+1 {{type mismatch between argument 2 of ReduceOp body and initial value 0}}
%num_elements = shape.reduce(%shape, %init) -> f32 {
^bb0(%index: index, %dim: !shape.size, %lci: !shape.size):
- "shape.yield"() : () -> ()
+ shape.yield
+ }
+}
+
+// -----
+
+func @yield_op_args_num_mismatch(%shape : !shape.shape, %init : !shape.size) {
+ // expected-error@+3 {{number of operands does not match number of results of its parent}}
+ %num_elements = shape.reduce(%shape, %init) -> !shape.size {
+ ^bb0(%index: index, %dim: !shape.size, %lci: !shape.size):
+ shape.yield %dim, %dim : !shape.size, !shape.size
+ }
+}
+
+// -----
+
+func @yield_op_type_mismatch(%shape : !shape.shape, %init : !shape.size) {
+ // expected-error@+4 {{types mismatch between yield op and its parent}}
+ %num_elements = shape.reduce(%shape, %init) -> !shape.size {
+ ^bb0(%index: index, %dim: !shape.size, %lci: !shape.size):
+ %c0 = constant 1 : index
+ shape.yield %c0 : index
}
}