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