1// RUN: mlir-tblgen -gen-op-defs -I %S/../../include %s | FileCheck %s
2
3include "mlir/IR/OpBase.td"
4include "mlir/Interfaces/InferTypeOpInterface.td"
5
6def Test_Dialect : Dialect {
7  let name = "test";
8}
9class NS_Op<string mnemonic, list<OpTrait> traits> :
10    Op<Test_Dialect, mnemonic, traits>;
11
12def OpA : NS_Op<"one_normal_result_op", []> {
13  let results = (outs I32:$result);
14}
15
16// CHECK-LABEL: void OpA::build
17// CHECK:         ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands
18// CHECK:         assert(resultTypes.size() == 1u && "mismatched number of return types");
19// CHECK-NEXT:    odsState.addTypes(resultTypes);
20
21def OpB : NS_Op<"same_input_output_type_op", [SameOperandsAndResultType]> {
22  let arguments = (ins I32:$x);
23  let results = (outs I32:$y);
24}
25
26// CHECK-LABEL: OpB definitions
27// CHECK: void OpB::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type y, ::mlir::Value x)
28// CHECK:   odsState.addTypes(y);
29// CHECK: void OpB::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Value x)
30// CHECK:   odsState.addTypes({x.getType()});
31
32def OpC : NS_Op<"three_normal_result_op", []> {
33  let results = (outs I32:$x, /*unnamed*/I32, I32:$z);
34}
35
36// CHECK-LABEL: OpC definitions
37// CHECK:       void OpC::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type x, ::mlir::Type resultType1, ::mlir::Type z)
38// CHECK-NEXT:   odsState.addTypes(x)
39// CHECK-NEXT:   odsState.addTypes(resultType1)
40// CHECK-NEXT:   odsState.addTypes(z)
41
42// CHECK:      void OpC::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes) {
43// CHECK-NEXT:   assert(resultTypes.size() == 3u && "mismatched number of results");
44// CHECK-NEXT:   odsState.addTypes(resultTypes);
45
46def IntegerTypeAttr : TypeAttrBase<"IntegerType", "Integer type attribute">;
47def OpD : NS_Op<"type_attr_as_result_type", [FirstAttrDerivedResultType]> {
48  let arguments = (ins I32:$x, IntegerTypeAttr:$attr, F32Attr:$f32);
49  let results = (outs AnyTensor:$y);
50}
51
52// CHECK-LABEL: OpD definitions
53// CHECK: void OpD::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes)
54// CHECK: odsState.addTypes({attr.second.cast<::mlir::TypeAttr>().getValue()});
55
56def OpE : NS_Op<"value_attr_as_result_type", [FirstAttrDerivedResultType]> {
57  let arguments = (ins I32:$x, F32Attr:$attr);
58  let results = (outs AnyTensor:$y);
59}
60
61// CHECK-LABEL: OpE definitions
62// CHECK: void OpE::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes)
63// CHECK: odsState.addTypes({attr.second.getType()});
64
65def OpF : NS_Op<"one_variadic_result_op", []> {
66  let results = (outs Variadic<I32>:$x);
67}
68
69// CHECK-LABEL: void OpF::build
70// CHECK-SAME:    ::mlir::TypeRange x
71// CHECK-NOT:     assert
72// CHECK:         odsState.addTypes(x);
73
74def OpG : NS_Op<"one_normal_and_one_variadic_result_op", []> {
75
76  let results = (outs I32:$x, Variadic<I32>:$y);
77}
78
79// CHECK-LABEL: OpG definitions
80
81// CHECK:      void OpG::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type x, ::mlir::TypeRange y)
82// CHECK-NEXT:   odsState.addTypes(x);
83// CHECK-NEXT:   odsState.addTypes(y);
84
85// CHECK:       void OpG::build
86// CHECK:         ::mlir::TypeRange resultTypes
87// CHECK:         assert(resultTypes.size() >= 1u && "mismatched number of return types");
88// CHECK-NEXT:    odsState.addTypes(resultTypes);
89
90def OpI : NS_Op<"mix_variadic_and_normal_results_op", [SameVariadicResultSize]> {
91  let results = (outs Variadic<AnyTensor>:$output1, AnyTensor:$output2, Variadic<AnyTensor>:$output3);
92}
93
94// CHECK-LABEL: ::mlir::Operation::result_range OpI::output1
95// CHECK-NEXT:    return getODSResults(0);
96
97// CHECK-LABEL: ::mlir::Value OpI::output2
98// CHECK-NEXT:    return *getODSResults(1).begin();
99
100// CHECK-LABEL: OpI::build
101// CHECK-NEXT:    odsState.addTypes(output1);
102// CHECK-NEXT:    odsState.addTypes(output2);
103// CHECK-NEXT:    odsState.addTypes(output3);
104
105// Test that if the only operand is variadic, we access the first value in the
106// pack to set result type
107// ---
108def OpK : NS_Op<"only_input_is_variadic_with_same_value_type_op", [SameOperandsAndResultType]> {
109  let arguments = (ins Variadic<AnyTensor>:$input);
110  let results = (outs AnyTensor:$result);
111}
112
113// CHECK-LABEL: OpK::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes)
114// CHECK: odsState.addTypes({operands[0].getType()});
115
116// Test with inferred shapes and interleaved with operands/attributes.
117//
118def OpL : NS_Op<"op_with_all_types_constraint",
119    [AllTypesMatch<["a", "b"]>]> {
120  let arguments = (ins I32Attr:$attr1, AnyType:$a);
121  let results = (outs Res<AnyType, "output b", []>:$b);
122}
123
124// CHECK-LABEL: LogicalResult OpL::inferReturnTypes
125// CHECK-NOT: }
126// CHECK: inferredReturnTypes[0] = operands[0].getType();
127