1//===- OpBuildGen.cpp - TableGen OpBuildGen Tests -------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Test TableGen generated build() methods on Operations.
10//
11//===----------------------------------------------------------------------===//
12
13#include "TestDialect.h"
14#include "TestOps.h"
15#include "mlir/IR/Attributes.h"
16#include "mlir/IR/Builders.h"
17#include "mlir/IR/BuiltinTypes.h"
18#include "mlir/IR/Dialect.h"
19#include "gmock/gmock.h"
20#include <vector>
21
22namespace mlir {
23
24//===----------------------------------------------------------------------===//
25// Test Fixture
26//===----------------------------------------------------------------------===//
27
28static MLIRContext &getContext() {
29 static MLIRContext ctx;
30 ctx.getOrLoadDialect<test::TestDialect>();
31 return ctx;
32}
33/// Test fixture for providing basic utilities for testing.
34class OpBuildGenTest : public ::testing::Test {
35protected:
36 OpBuildGenTest()
37 : ctx(getContext()), builder(&ctx), loc(builder.getUnknownLoc()),
38 i32Ty(builder.getI32Type()), f32Ty(builder.getF32Type()),
39 cstI32(builder.create<test::TableGenConstant>(loc, i32Ty)),
40 cstF32(builder.create<test::TableGenConstant>(loc, f32Ty)),
41 noAttrs(), attrStorage{builder.getNamedAttr(name: "attr0",
42 val: builder.getBoolAttr(value: true)),
43 builder.getNamedAttr(
44 "attr1", builder.getI32IntegerAttr(33))},
45 attrs(attrStorage) {}
46
47 // Verify that `op` has the given set of result types, operands, and
48 // attributes.
49 template <typename OpTy>
50 void verifyOp(OpTy &&concreteOp, std::vector<Type> resultTypes,
51 std::vector<Value> operands,
52 std::vector<NamedAttribute> attrs) {
53 ASSERT_NE(concreteOp, nullptr);
54 Operation *op = concreteOp.getOperation();
55
56 EXPECT_EQ(op->getNumResults(), resultTypes.size());
57 for (unsigned idx : llvm::seq(Begin: 0U, End: op->getNumResults()))
58 EXPECT_EQ(op->getResult(idx).getType(), resultTypes[idx]);
59
60 EXPECT_EQ(op->getNumOperands(), operands.size());
61 for (unsigned idx : llvm::seq(Begin: 0U, End: op->getNumOperands()))
62 EXPECT_EQ(op->getOperand(idx), operands[idx]);
63
64 EXPECT_EQ(op->getAttrs().size(), attrs.size());
65 for (unsigned idx : llvm::seq<unsigned>(Begin: 0U, End: attrs.size()))
66 EXPECT_EQ(op->getAttr(attrs[idx].getName().strref()),
67 attrs[idx].getValue());
68
69 concreteOp.erase();
70 }
71
72 // Helper method to test ops with inferred result types and single variadic
73 // input.
74 template <typename OpTy>
75 void testSingleVariadicInputInferredType() {
76 // Test separate arg, separate param build method.
77 auto op = builder.create<OpTy>(loc, i32Ty, ValueRange{*cstI32, *cstI32});
78 verifyOp(std::move(op), {i32Ty}, {*cstI32, *cstI32}, noAttrs);
79
80 // Test collective params build method.
81 op = builder.create<OpTy>(loc, TypeRange{i32Ty},
82 ValueRange{*cstI32, *cstI32});
83 verifyOp(std::move(op), {i32Ty}, {*cstI32, *cstI32}, noAttrs);
84
85 // Test build method with no result types, default value of attributes.
86 op = builder.create<OpTy>(loc, ValueRange{*cstI32, *cstI32});
87 verifyOp(std::move(op), {i32Ty}, {*cstI32, *cstI32}, noAttrs);
88
89 // Test build method with no result types and supplied attributes.
90 op = builder.create<OpTy>(loc, ValueRange{*cstI32, *cstI32}, attrs);
91 verifyOp(std::move(op), {i32Ty}, {*cstI32, *cstI32}, attrs);
92 }
93
94protected:
95 MLIRContext &ctx;
96 OpBuilder builder;
97 Location loc;
98 Type i32Ty;
99 Type f32Ty;
100 OwningOpRef<test::TableGenConstant> cstI32;
101 OwningOpRef<test::TableGenConstant> cstF32;
102
103 ArrayRef<NamedAttribute> noAttrs;
104 std::vector<NamedAttribute> attrStorage;
105 ArrayRef<NamedAttribute> attrs;
106};
107
108/// Test basic build methods.
109TEST_F(OpBuildGenTest, BasicBuildMethods) {
110 // Test separate args, separate results build method.
111 auto op = builder.create<test::TableGenBuildOp0>(loc, i32Ty, *cstI32);
112 verifyOp(op, {i32Ty}, {*cstI32}, noAttrs);
113
114 // Test separate args, collective results build method.
115 op = builder.create<test::TableGenBuildOp0>(loc, TypeRange{i32Ty}, *cstI32);
116 verifyOp(op, {i32Ty}, {*cstI32}, noAttrs);
117
118 // Test collective args, collective params build method.
119 op = builder.create<test::TableGenBuildOp0>(loc, TypeRange{i32Ty},
120 ValueRange{*cstI32});
121 verifyOp(op, {i32Ty}, {*cstI32}, noAttrs);
122
123 // Test collective args, collective results, non-empty attributes
124 op = builder.create<test::TableGenBuildOp0>(loc, TypeRange{i32Ty},
125 ValueRange{*cstI32}, attrs);
126 verifyOp(op, {i32Ty}, {*cstI32}, attrs);
127}
128
129/// The following 3 tests exercise build methods generated for operations
130/// with a combination of:
131///
132/// single variadic arg x
133/// {single variadic result, non-variadic result, multiple variadic results}
134///
135/// Specifically to test that ODS framework does not generate ambiguous
136/// build() methods that fail to compile.
137
138/// Test build methods for an Op with a single varadic arg and a single
139/// variadic result.
140TEST_F(OpBuildGenTest, BuildMethodsSingleVariadicArgAndResult) {
141 // Test collective args, collective results method, building a unary op.
142 auto op = builder.create<test::TableGenBuildOp1>(loc, TypeRange{i32Ty},
143 ValueRange{*cstI32});
144 verifyOp(op, {i32Ty}, {*cstI32}, noAttrs);
145
146 // Test collective args, collective results method, building a unary op with
147 // named attributes.
148 op = builder.create<test::TableGenBuildOp1>(loc, TypeRange{i32Ty},
149 ValueRange{*cstI32}, attrs);
150 verifyOp(op, {i32Ty}, {*cstI32}, attrs);
151
152 // Test collective args, collective results method, building a binary op.
153 op = builder.create<test::TableGenBuildOp1>(loc, TypeRange{i32Ty, f32Ty},
154 ValueRange{*cstI32, *cstF32});
155 verifyOp(op, {i32Ty, f32Ty}, {*cstI32, *cstF32}, noAttrs);
156
157 // Test collective args, collective results method, building a binary op with
158 // named attributes.
159 op = builder.create<test::TableGenBuildOp1>(
160 loc, TypeRange{i32Ty, f32Ty}, ValueRange{*cstI32, *cstF32}, attrs);
161 verifyOp(op, {i32Ty, f32Ty}, {*cstI32, *cstF32}, attrs);
162}
163
164/// Test build methods for an Op with a single varadic arg and a non-variadic
165/// result.
166TEST_F(OpBuildGenTest, BuildMethodsSingleVariadicArgNonVariadicResults) {
167 // Test separate arg, separate param build method.
168 auto op =
169 builder.create<test::TableGenBuildOp1>(loc, i32Ty, ValueRange{*cstI32});
170 verifyOp(op, {i32Ty}, {*cstI32}, noAttrs);
171
172 // Test collective params build method, no attributes.
173 op = builder.create<test::TableGenBuildOp1>(loc, TypeRange{i32Ty},
174 ValueRange{*cstI32});
175 verifyOp(op, {i32Ty}, {*cstI32}, noAttrs);
176
177 // Test collective params build method no attributes, 2 inputs.
178 op = builder.create<test::TableGenBuildOp1>(loc, TypeRange{i32Ty},
179 ValueRange{*cstI32, *cstF32});
180 verifyOp(op, {i32Ty}, {*cstI32, *cstF32}, noAttrs);
181
182 // Test collective params build method, non-empty attributes.
183 op = builder.create<test::TableGenBuildOp1>(
184 loc, TypeRange{i32Ty}, ValueRange{*cstI32, *cstF32}, attrs);
185 verifyOp(op, {i32Ty}, {*cstI32, *cstF32}, attrs);
186}
187
188/// Test build methods for an Op with a single varadic arg and multiple variadic
189/// result.
190TEST_F(OpBuildGenTest,
191 BuildMethodsSingleVariadicArgAndMultipleVariadicResults) {
192 // Test separate arg, separate param build method.
193 auto op = builder.create<test::TableGenBuildOp3>(
194 loc, TypeRange{i32Ty}, TypeRange{f32Ty}, ValueRange{*cstI32});
195 verifyOp(op, {i32Ty, f32Ty}, {*cstI32}, noAttrs);
196
197 // Test collective params build method, no attributes.
198 op = builder.create<test::TableGenBuildOp3>(loc, TypeRange{i32Ty, f32Ty},
199 ValueRange{*cstI32});
200 verifyOp(op, {i32Ty, f32Ty}, {*cstI32}, noAttrs);
201
202 // Test collective params build method, with attributes.
203 op = builder.create<test::TableGenBuildOp3>(loc, TypeRange{i32Ty, f32Ty},
204 ValueRange{*cstI32}, attrs);
205 verifyOp(op, {i32Ty, f32Ty}, {*cstI32}, attrs);
206}
207
208// The next test checks supression of ambiguous build methods for ops that
209// have a single variadic input, and single non-variadic result, and which
210// support the SameOperandsAndResultType trait and and optionally the
211// InferOpTypeInterface interface. For such ops, the ODS framework generates
212// build methods with no result types as they are inferred from the input types.
213TEST_F(OpBuildGenTest, BuildMethodsSameOperandsAndResultTypeSuppression) {
214 testSingleVariadicInputInferredType<test::TableGenBuildOp4>();
215}
216
217TEST_F(OpBuildGenTest, BuildMethodsRegionsAndInferredType) {
218 auto op = builder.create<test::TableGenBuildOp5>(
219 loc, ValueRange{*cstI32, *cstF32}, /*attributes=*/noAttrs);
220 ASSERT_EQ(op->getNumRegions(), 1u);
221 verifyOp(op, {i32Ty}, {*cstI32, *cstF32}, noAttrs);
222}
223
224} // namespace mlir
225

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of mlir/unittests/TableGen/OpBuildGen.cpp