@@ -66,29 +66,44 @@ class OpBuildGenTest : public ::testing::Test {
66
66
EXPECT_EQ (op->getAttr (attrs[idx].getName ().strref ()),
67
67
attrs[idx].getValue ());
68
68
69
+ EXPECT_TRUE (mlir::succeeded (concreteOp.verify ()));
69
70
concreteOp.erase ();
70
71
}
71
72
72
- // Helper method to test ops with inferred result types and single variadic
73
- // input.
74
73
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);
74
+ void verifyOp (OpTy &&concreteOp, std::vector<Type> resultTypes,
75
+ std::vector<Value> operands1, std::vector<Value> operands2,
76
+ std::vector<NamedAttribute> attrs) {
77
+ ASSERT_NE (concreteOp, nullptr );
78
+ Operation *op = concreteOp.getOperation ();
79
+
80
+ EXPECT_EQ (op->getNumResults (), resultTypes.size ());
81
+ for (unsigned idx : llvm::seq (0U , op->getNumResults ()))
82
+ EXPECT_EQ (op->getResult (idx).getType (), resultTypes[idx]);
83
+
84
+ auto operands = llvm::to_vector (llvm::concat<Value>(operands1, operands2));
85
+ EXPECT_EQ (op->getNumOperands (), operands.size ());
86
+ for (unsigned idx : llvm::seq (0U , op->getNumOperands ()))
87
+ EXPECT_EQ (op->getOperand (idx), operands[idx]);
88
+
89
+ EXPECT_EQ (op->getAttrs ().size (), attrs.size ());
90
+ if (op->getAttrs ().size () != attrs.size ()) {
91
+ // Simple export where there is mismatch count.
92
+ llvm::errs () << " Op attrs:\n " ;
93
+ for (auto it : op->getAttrs ())
94
+ llvm::errs () << " \t " << it.getName () << " = " << it.getValue () << " \n " ;
95
+
96
+ llvm::errs () << " Expected attrs:\n " ;
97
+ for (auto it : attrs)
98
+ llvm::errs () << " \t " << it.getName () << " = " << it.getValue () << " \n " ;
99
+ } else {
100
+ for (unsigned idx : llvm::seq<unsigned >(0U , attrs.size ()))
101
+ EXPECT_EQ (op->getAttr (attrs[idx].getName ().strref ()),
102
+ attrs[idx].getValue ());
103
+ }
104
+
105
+ EXPECT_TRUE (mlir::succeeded (concreteOp.verify ()));
106
+ concreteOp.erase ();
92
107
}
93
108
94
109
protected:
@@ -205,13 +220,31 @@ TEST_F(OpBuildGenTest,
205
220
verifyOp (op, {i32Ty, f32Ty}, {*cstI32}, attrs);
206
221
}
207
222
208
- // The next test checks supression of ambiguous build methods for ops that
223
+ // The next test checks suppression of ambiguous build methods for ops that
209
224
// have a single variadic input, and single non-variadic result, and which
210
- // support the SameOperandsAndResultType trait and and optionally the
225
+ // support the SameOperandsAndResultType trait and optionally the
211
226
// InferOpTypeInterface interface. For such ops, the ODS framework generates
212
227
// build methods with no result types as they are inferred from the input types.
213
228
TEST_F (OpBuildGenTest, BuildMethodsSameOperandsAndResultTypeSuppression) {
214
- testSingleVariadicInputInferredType<test::TableGenBuildOp4>();
229
+ // Test separate arg, separate param build method.
230
+ auto op = builder.create <test::TableGenBuildOp4>(
231
+ loc, i32Ty, ValueRange{*cstI32, *cstI32});
232
+ verifyOp (std::move (op), {i32Ty}, {*cstI32, *cstI32}, noAttrs);
233
+
234
+ // Test collective params build method.
235
+ op = builder.create <test::TableGenBuildOp4>(loc, TypeRange{i32Ty},
236
+ ValueRange{*cstI32, *cstI32});
237
+ verifyOp (std::move (op), {i32Ty}, {*cstI32, *cstI32}, noAttrs);
238
+
239
+ // Test build method with no result types, default value of attributes.
240
+ op =
241
+ builder.create <test::TableGenBuildOp4>(loc, ValueRange{*cstI32, *cstI32});
242
+ verifyOp (std::move (op), {i32Ty}, {*cstI32, *cstI32}, noAttrs);
243
+
244
+ // Test build method with no result types and supplied attributes.
245
+ op = builder.create <test::TableGenBuildOp4>(loc, ValueRange{*cstI32, *cstI32},
246
+ attrs);
247
+ verifyOp (std::move (op), {i32Ty}, {*cstI32, *cstI32}, attrs);
215
248
}
216
249
217
250
TEST_F (OpBuildGenTest, BuildMethodsRegionsAndInferredType) {
@@ -221,4 +254,41 @@ TEST_F(OpBuildGenTest, BuildMethodsRegionsAndInferredType) {
221
254
verifyOp (op, {i32Ty}, {*cstI32, *cstF32}, noAttrs);
222
255
}
223
256
257
+ TEST_F (OpBuildGenTest, BuildMethodsVariadicProperties) {
258
+ // Account for conversion as part of getAttrs().
259
+ std::vector<NamedAttribute> noAttrsStorage;
260
+ auto segmentSize = builder.getNamedAttr (" operandSegmentSizes" ,
261
+ builder.getDenseI32ArrayAttr ({1 , 1 }));
262
+ noAttrsStorage.push_back (segmentSize);
263
+ ArrayRef<NamedAttribute> noAttrs (noAttrsStorage);
264
+ std::vector<NamedAttribute> attrsStorage = this ->attrStorage ;
265
+ attrsStorage.push_back (segmentSize);
266
+ ArrayRef<NamedAttribute> attrs (attrsStorage);
267
+
268
+ // Test separate arg, separate param build method.
269
+ auto op = builder.create <test::TableGenBuildOp6>(
270
+ loc, f32Ty, ValueRange{*cstI32}, ValueRange{*cstI32});
271
+ verifyOp (std::move (op), {f32Ty}, {*cstI32}, {*cstI32}, noAttrs);
272
+
273
+ // Test build method with no result types, default value of attributes.
274
+ op = builder.create <test::TableGenBuildOp6>(loc, ValueRange{*cstI32},
275
+ ValueRange{*cstI32});
276
+ verifyOp (std::move (op), {f32Ty}, {*cstI32}, {*cstI32}, noAttrs);
277
+
278
+ // Test collective params build method.
279
+ op = builder.create <test::TableGenBuildOp6>(
280
+ loc, TypeRange{f32Ty}, ValueRange{*cstI32}, ValueRange{*cstI32});
281
+ verifyOp (std::move (op), {f32Ty}, {*cstI32}, {*cstI32}, noAttrs);
282
+
283
+ // Test build method with result types, supplied attributes.
284
+ op = builder.create <test::TableGenBuildOp6>(
285
+ loc, TypeRange{f32Ty}, ValueRange{*cstI32, *cstI32}, attrs);
286
+ verifyOp (std::move (op), {f32Ty}, {*cstI32}, {*cstI32}, attrs);
287
+
288
+ // Test build method with no result types and supplied attributes.
289
+ op = builder.create <test::TableGenBuildOp6>(loc, ValueRange{*cstI32, *cstI32},
290
+ attrs);
291
+ verifyOp (std::move (op), {f32Ty}, {*cstI32}, {*cstI32}, attrs);
292
+ }
293
+
224
294
} // namespace mlir
0 commit comments