!listconcat([NoSideEffect, SameOperandsAndResultType], traits)>,
Arguments<(ins LLVM_Type:$lhs, LLVM_Type:$rhs)>,
LLVM_Builder<"$res = builder." # builderFunc # "($lhs, $rhs);"> {
- let parser = [{ return impl::parseBinaryOp(parser, result); }];
- let printer = [{ mlir::impl::printBinaryOp(this->getOperation(), p); }];
+ let parser = [{ return impl::parseOneResultSameOperandTypeOp(parser, result); }];
+ let printer = [{ mlir::impl::printOneResultOp(this->getOperation(), p); }];
}
// Integer binary operations.
SPV_ScalarOrVectorOf<resultType>:$result
);
- let parser = [{ return impl::parseBinaryOp(parser, result); }];
- let printer = [{ return impl::printBinaryOp(getOperation(), p); }];
+ let parser = [{ return impl::parseOneResultSameOperandTypeOp(parser, result); }];
+ let printer = [{ return impl::printOneResultOp(getOperation(), p); }];
// No additional verification needed in addition to the ODS-generated ones.
let verifier = [{ return success(); }];
}
SPV_ScalarOrVectorOf<resultType>:$result
);
- let parser = [{ return impl::parseBinaryOp(parser, result); }];
+ let parser = [{ return impl::parseOneResultSameOperandTypeOp(parser, result); }];
- let printer = [{ return impl::printBinaryOp(getOperation(), p); }];
+ let printer = [{ return impl::printOneResultOp(getOperation(), p); }];
let verifier = [{ return success(); }];
}
let results = (outs AnyType);
let parser = [{
- return impl::parseBinaryOp(parser, result);
+ return impl::parseOneResultSameOperandTypeOp(parser, result);
}];
let printer = [{
namespace impl {
void buildBinaryOp(Builder *builder, OperationState &result, Value *lhs,
Value *rhs);
-ParseResult parseBinaryOp(OpAsmParser &parser, OperationState &result);
+ParseResult parseOneResultSameOperandTypeOp(OpAsmParser &parser,
+ OperationState &result);
// Prints the given binary `op` in custom assembly form if both the two operands
// and the result have the same time. Otherwise, prints the generic assembly
// form.
-void printBinaryOp(Operation *op, OpAsmPrinter &p);
+void printOneResultOp(Operation *op, OpAsmPrinter &p);
} // namespace impl
// These functions are out-of-line implementations of the methods in CastOp,
result.types.push_back(lhs->getType());
}
-ParseResult impl::parseBinaryOp(OpAsmParser &parser, OperationState &result) {
+ParseResult impl::parseOneResultSameOperandTypeOp(OpAsmParser &parser,
+ OperationState &result) {
SmallVector<OpAsmParser::OperandType, 2> ops;
Type type;
- return failure(parser.parseOperandList(ops, 2) ||
+ return failure(parser.parseOperandList(ops) ||
parser.parseOptionalAttributeDict(result.attributes) ||
parser.parseColonType(type) ||
parser.resolveOperands(ops, type, result.operands) ||
parser.addTypeToList(type, result.types));
}
-void impl::printBinaryOp(Operation *op, OpAsmPrinter &p) {
- assert(op->getNumOperands() == 2 && "binary op should have two operands");
- assert(op->getNumResults() == 1 && "binary op should have one result");
+void impl::printOneResultOp(Operation *op, OpAsmPrinter &p) {
+ assert(op->getNumResults() == 1 && "op should have one result");
// If not all the operand and result types are the same, just use the
// generic assembly form to avoid omitting information in printing.
auto resultType = op->getResult(0)->getType();
- if (op->getOperand(0)->getType() != resultType ||
- op->getOperand(1)->getType() != resultType) {
+ if (llvm::any_of(op->getOperandTypes(),
+ [&](Type type) { return type != resultType; })) {
p.printGenericOp(op);
return;
}
- p << op->getName() << ' ' << *op->getOperand(0) << ", " << *op->getOperand(1);
+ p << op->getName() << ' ';
+ p.printOperands(op->getOperands());
p.printOptionalAttrDict(op->getAttrs());
// Now we can output only one type for all operands and the result.
- p << " : " << op->getResult(0)->getType();
+ p << " : " << resultType;
}
//===----------------------------------------------------------------------===//
func @func_with_ops(f32) {
^bb0(%a : f32):
- %sf = addf %a, %a, %a : f32 // expected-error {{custom op 'std.addf' expected 2 operands}}
+ %sf = addf %a, %a, %a : f32 // expected-error {{'std.addf' op expected 2 operands}}
}
// -----
func @func_with_ops(f32) {
^bb0(%a : f32):
- %sf = addf(%a, %a) : f32 // expected-error {{unexpected delimiter}}
+ %sf = addf(%a, %a) : f32 // expected-error {{expected ':'}}
}
// -----
func @func_with_ops(f32) {
^bb0(%a : f32):
- %sf = addf{%a, %a} : f32 // expected-error {{invalid operand}}
+ %sf = addf{%a, %a} : f32 // expected-error {{expected attribute name}}
}
// -----