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 "mlir/IR/Attributes.h" 15 #include "mlir/IR/Builders.h" 16 #include "mlir/IR/Dialect.h" 17 #include "mlir/IR/Identifier.h" 18 #include "mlir/IR/StandardTypes.h" 19 #include "gmock/gmock.h" 20 #include <vector> 21 22 namespace mlir { 23 24 //===----------------------------------------------------------------------===// 25 // Test Fixture 26 //===----------------------------------------------------------------------===// 27 28 /// Test fixture for providing basic utilities for testing. 29 class OpBuildGenTest : public ::testing::Test { 30 protected: 31 OpBuildGenTest() 32 : ctx{}, builder(&ctx), loc(builder.getUnknownLoc()), 33 i32Ty(builder.getI32Type()), f32Ty(builder.getF32Type()), 34 cstI32(builder.create<TableGenConstant>(loc, i32Ty)), 35 cstF32(builder.create<TableGenConstant>(loc, f32Ty)), 36 noAttrs(), attrStorage{builder.getNamedAttr("attr0", 37 builder.getBoolAttr(true)), 38 builder.getNamedAttr( 39 "attr1", builder.getI32IntegerAttr(33))}, 40 attrs(attrStorage) {} 41 42 // Verify that `op` has the given set of result types, operands, and 43 // attributes. 44 template <typename OpTy> 45 void verifyOp(OpTy &&concreteOp, std::vector<Type> resultTypes, 46 std::vector<Value> operands, 47 std::vector<NamedAttribute> attrs) { 48 ASSERT_NE(concreteOp, nullptr); 49 Operation *op = concreteOp.getOperation(); 50 51 EXPECT_EQ(op->getNumResults(), resultTypes.size()); 52 for (unsigned idx : llvm::seq(0U, op->getNumResults())) 53 EXPECT_EQ(op->getResult(idx).getType(), resultTypes[idx]); 54 55 EXPECT_EQ(op->getNumOperands(), operands.size()); 56 for (unsigned idx : llvm::seq(0U, op->getNumOperands())) 57 EXPECT_EQ(op->getOperand(idx), operands[idx]); 58 59 EXPECT_EQ(op->getAttrs().size(), attrs.size()); 60 for (unsigned idx : llvm::seq<unsigned>(0U, attrs.size())) 61 EXPECT_EQ(op->getAttr(attrs[idx].first.strref()), attrs[idx].second); 62 63 concreteOp.erase(); 64 } 65 66 protected: 67 MLIRContext ctx; 68 OpBuilder builder; 69 Location loc; 70 Type i32Ty; 71 Type f32Ty; 72 TableGenConstant cstI32; 73 TableGenConstant cstF32; 74 75 ArrayRef<NamedAttribute> noAttrs; 76 std::vector<NamedAttribute> attrStorage; 77 ArrayRef<NamedAttribute> attrs; 78 }; 79 80 /// Test basic build methods. 81 TEST_F(OpBuildGenTest, BasicBuildMethods) { 82 // Test separate args, separate results build method. 83 auto op = builder.create<TableGenBuildOp0>(loc, i32Ty, cstI32); 84 verifyOp(op, {i32Ty}, {cstI32}, noAttrs); 85 86 // Test separate args, collective results build method. 87 op = builder.create<TableGenBuildOp0>(loc, ArrayRef<Type>{i32Ty}, cstI32); 88 verifyOp(op, {i32Ty}, {cstI32}, noAttrs); 89 90 // Test collective args, collective params build method. 91 op = builder.create<TableGenBuildOp0>(loc, ArrayRef<Type>{i32Ty}, 92 ArrayRef<Value>{cstI32}); 93 verifyOp(op, {i32Ty}, {cstI32}, noAttrs); 94 95 // Test collective args, collective results, non-empty attributes 96 op = builder.create<TableGenBuildOp0>(loc, ArrayRef<Type>{i32Ty}, 97 ArrayRef<Value>{cstI32}, attrs); 98 verifyOp(op, {i32Ty}, {cstI32}, attrs); 99 } 100 101 /// The following 3 tests exercise build methods generated for operations 102 /// with a combination of: 103 /// 104 /// single variadic arg x 105 /// {single variadic result, non-variadic result, multiple variadic results} 106 /// 107 /// Specifically to test that that ODS framework does not generate ambiguous 108 /// build() methods that fail to compile. 109 110 /// Test build methods for an Op with a single varadic arg and a single 111 /// variadic result. 112 TEST_F(OpBuildGenTest, BuildMethodsSingleVariadicArgAndResult) { 113 // Test collective args, collective results method, building a unary op. 114 auto op = builder.create<TableGenBuildOp1>(loc, ArrayRef<Type>{i32Ty}, 115 ArrayRef<Value>{cstI32}); 116 verifyOp(std::move(op), {i32Ty}, {cstI32}, noAttrs); 117 118 // Test collective args, collective results method, building a unary op with 119 // named attributes. 120 op = builder.create<TableGenBuildOp1>(loc, ArrayRef<Type>{i32Ty}, 121 ArrayRef<Value>{cstI32}, attrs); 122 verifyOp(std::move(op), {i32Ty}, {cstI32}, attrs); 123 124 // Test collective args, collective results method, building a binary op. 125 op = builder.create<TableGenBuildOp1>(loc, ArrayRef<Type>{i32Ty, f32Ty}, 126 ArrayRef<Value>{cstI32, cstF32}); 127 verifyOp(std::move(op), {i32Ty, f32Ty}, {cstI32, cstF32}, noAttrs); 128 129 // Test collective args, collective results method, building a binary op with 130 // named attributes. 131 op = builder.create<TableGenBuildOp1>(loc, ArrayRef<Type>{i32Ty, f32Ty}, 132 ArrayRef<Value>{cstI32, cstF32}, attrs); 133 verifyOp(std::move(op), {i32Ty, f32Ty}, {cstI32, cstF32}, attrs); 134 } 135 136 /// Test build methods for an Op with a single varadic arg and a non-variadic 137 /// result. 138 TEST_F(OpBuildGenTest, BuildMethodsSingleVariadicArgNonVariadicResults) { 139 // Test separate arg, separate param build method. 140 auto op = 141 builder.create<TableGenBuildOp1>(loc, i32Ty, ArrayRef<Value>{cstI32}); 142 verifyOp(std::move(op), {i32Ty}, {cstI32}, noAttrs); 143 144 // Test collective params build method, no attributes. 145 op = builder.create<TableGenBuildOp1>(loc, ArrayRef<Type>{i32Ty}, 146 ArrayRef<Value>{cstI32}); 147 verifyOp(std::move(op), {i32Ty}, {cstI32}, noAttrs); 148 149 // Test collective params build method no attributes, 2 inputs. 150 op = builder.create<TableGenBuildOp1>(loc, ArrayRef<Type>{i32Ty}, 151 ArrayRef<Value>{cstI32, cstF32}); 152 verifyOp(std::move(op), {i32Ty}, {cstI32, cstF32}, noAttrs); 153 154 // Test collective params build method, non-empty attributes. 155 op = builder.create<TableGenBuildOp1>(loc, ArrayRef<Type>{i32Ty}, 156 ArrayRef<Value>{cstI32, cstF32}, attrs); 157 verifyOp(std::move(op), {i32Ty}, {cstI32, cstF32}, attrs); 158 } 159 160 /// Test build methods for an Op with a single varadic arg and multiple variadic 161 /// result. 162 TEST_F(OpBuildGenTest, 163 BuildMethodsSingleVariadicArgAndMultipleVariadicResults) { 164 // Test separate arg, separate param build method. 165 auto op = builder.create<TableGenBuildOp3>(loc, ArrayRef<Type>{i32Ty}, 166 ArrayRef<Type>{f32Ty}, 167 ArrayRef<Value>{cstI32}); 168 verifyOp(std::move(op), {i32Ty, f32Ty}, {cstI32}, noAttrs); 169 170 // Test collective params build method, no attributes. 171 op = builder.create<TableGenBuildOp3>(loc, ArrayRef<Type>{i32Ty, f32Ty}, 172 ArrayRef<Value>{cstI32}); 173 verifyOp(std::move(op), {i32Ty, f32Ty}, {cstI32}, noAttrs); 174 175 // Test collective params build method, with attributes. 176 op = builder.create<TableGenBuildOp3>(loc, ArrayRef<Type>{i32Ty, f32Ty}, 177 ArrayRef<Value>{cstI32}, attrs); 178 verifyOp(std::move(op), {i32Ty, f32Ty}, {cstI32}, attrs); 179 } 180 181 } // namespace mlir 182