[Mlir-commits] [mlir] 0b161de - [MLIR] Add unit test for tblgen Op build methods

Rahul Joshi llvmlistbot at llvm.org
Tue Jul 28 15:43:51 PDT 2020


Author: Rahul Joshi
Date: 2020-07-28T15:43:37-07:00
New Revision: 0b161def6cacff1a63d3cf1a1efe95b550814d7a

URL: https://github.com/llvm/llvm-project/commit/0b161def6cacff1a63d3cf1a1efe95b550814d7a
DIFF: https://github.com/llvm/llvm-project/commit/0b161def6cacff1a63d3cf1a1efe95b550814d7a.diff

LOG: [MLIR] Add unit test for tblgen Op build methods

- Initiate the unit test with a test that tests variants of build() methods
  generated for ops with variadic operands and results.
- The intent is to migrate unit .td tests in mlir/test/mlir-tblgen that check for
  generated C++ code to these unit tests which test both that the generated code
  compiles and also is functionally correct.

Differential Revision: https://reviews.llvm.org/D84074

Added: 
    mlir/unittests/TableGen/OpBuildGen.cpp

Modified: 
    mlir/test/lib/Dialect/Test/TestOps.td
    mlir/unittests/TableGen/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td
index 528d219f70c7..af20034abd9b 100644
--- a/mlir/test/lib/Dialect/Test/TestOps.td
+++ b/mlir/test/lib/Dialect/Test/TestOps.td
@@ -1473,4 +1473,36 @@ def RegionIfOp : TEST_Op<"region_if",
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// Test TableGen generated build() methods
+//===----------------------------------------------------------------------===//
+
+def TableGenConstant : TEST_Op<"tblgen_constant"> {
+  let results = (outs AnyType);
+}
+
+// No variadic args or results.
+def TableGenBuildOp0 : TEST_Op<"tblgen_build_0"> {
+  let arguments = (ins AnyType:$value);
+  let results = (outs AnyType:$result);
+}
+
+// Sigle variadic arg and single variadic results.
+def TableGenBuildOp1 : TEST_Op<"tblgen_build_1"> {
+  let arguments = (ins Variadic<AnyType>:$inputs);
+  let results = (outs Variadic<AnyType>:$results);
+}
+
+// Single variadic arg and non-variadic results.
+def TableGenBuildOp2 : TEST_Op<"tblgen_build_2"> {
+  let arguments = (ins Variadic<AnyType>:$inputs);
+  let results = (outs AnyType:$result);
+}
+
+// Single variadic arg and multiple variadic results.
+def TableGenBuildOp3 : TEST_Op<"tblgen_build_3", [SameVariadicResultSize]> {
+  let arguments = (ins Variadic<AnyType>:$inputs);
+  let results = (outs Variadic<AnyType>:$resultA, Variadic<AnyType>:$resultB);
+}
+
 #endif // TEST_OPS

diff  --git a/mlir/unittests/TableGen/CMakeLists.txt b/mlir/unittests/TableGen/CMakeLists.txt
index cb4dea6918b8..7cee691de400 100644
--- a/mlir/unittests/TableGen/CMakeLists.txt
+++ b/mlir/unittests/TableGen/CMakeLists.txt
@@ -12,10 +12,17 @@ add_mlir_unittest(MLIRTableGenTests
   EnumsGenTest.cpp
   StructsGenTest.cpp
   FormatTest.cpp
+  OpBuildGen.cpp
 )
 
 add_dependencies(MLIRTableGenTests MLIRTableGenEnumsIncGen)
 add_dependencies(MLIRTableGenTests MLIRTableGenStructAttrIncGen)
+add_dependencies(MLIRTableGenTests MLIRTestDialect)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../test/lib/Dialect/Test)
+include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../test/lib/Dialect/Test)
 
 target_link_libraries(MLIRTableGenTests
-  PRIVATE MLIRTableGen MLIRIR)
+  PRIVATE MLIRTableGen MLIRIR
+  PUBLIC MLIRTestDialect
+)

diff  --git a/mlir/unittests/TableGen/OpBuildGen.cpp b/mlir/unittests/TableGen/OpBuildGen.cpp
new file mode 100644
index 000000000000..e90f96b87d63
--- /dev/null
+++ b/mlir/unittests/TableGen/OpBuildGen.cpp
@@ -0,0 +1,181 @@
+//===- 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/Dialect.h"
+#include "mlir/IR/Identifier.h"
+#include "mlir/IR/StandardTypes.h"
+#include "gmock/gmock.h"
+#include <vector>
+
+namespace mlir {
+
+//===----------------------------------------------------------------------===//
+// Test Fixture
+//===----------------------------------------------------------------------===//
+
+/// Test fixture for providing basic utilities for testing.
+class OpBuildGenTest : public ::testing::Test {
+protected:
+  OpBuildGenTest()
+      : ctx{}, builder(&ctx), loc(builder.getUnknownLoc()),
+        i32Ty(builder.getI32Type()), f32Ty(builder.getF32Type()),
+        cstI32(builder.create<TableGenConstant>(loc, i32Ty)),
+        cstF32(builder.create<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].first.strref()), attrs[idx].second);
+
+    concreteOp.erase();
+  }
+
+protected:
+  MLIRContext ctx;
+  OpBuilder builder;
+  Location loc;
+  Type i32Ty;
+  Type f32Ty;
+  TableGenConstant cstI32;
+  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<TableGenBuildOp0>(loc, i32Ty, cstI32);
+  verifyOp(op, {i32Ty}, {cstI32}, noAttrs);
+
+  // Test separate args, collective results build method.
+  op = builder.create<TableGenBuildOp0>(loc, ArrayRef<Type>{i32Ty}, cstI32);
+  verifyOp(op, {i32Ty}, {cstI32}, noAttrs);
+
+  // Test collective args, collective params build method.
+  op = builder.create<TableGenBuildOp0>(loc, ArrayRef<Type>{i32Ty},
+                                        ArrayRef<Value>{cstI32});
+  verifyOp(op, {i32Ty}, {cstI32}, noAttrs);
+
+  // Test collective args, collective results, non-empty attributes
+  op = builder.create<TableGenBuildOp0>(loc, ArrayRef<Type>{i32Ty},
+                                        ArrayRef<Value>{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<TableGenBuildOp1>(loc, ArrayRef<Type>{i32Ty},
+                                             ArrayRef<Value>{cstI32});
+  verifyOp(std::move(op), {i32Ty}, {cstI32}, noAttrs);
+
+  // Test collective args, collective results method, building a unary op with
+  // named attributes.
+  op = builder.create<TableGenBuildOp1>(loc, ArrayRef<Type>{i32Ty},
+                                        ArrayRef<Value>{cstI32}, attrs);
+  verifyOp(std::move(op), {i32Ty}, {cstI32}, attrs);
+
+  // Test collective args, collective results method, building a binary op.
+  op = builder.create<TableGenBuildOp1>(loc, ArrayRef<Type>{i32Ty, f32Ty},
+                                        ArrayRef<Value>{cstI32, cstF32});
+  verifyOp(std::move(op), {i32Ty, f32Ty}, {cstI32, cstF32}, noAttrs);
+
+  // Test collective args, collective results method, building a binary op with
+  // named attributes.
+  op = builder.create<TableGenBuildOp1>(loc, ArrayRef<Type>{i32Ty, f32Ty},
+                                        ArrayRef<Value>{cstI32, cstF32}, attrs);
+  verifyOp(std::move(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<TableGenBuildOp1>(loc, i32Ty, ArrayRef<Value>{cstI32});
+  verifyOp(std::move(op), {i32Ty}, {cstI32}, noAttrs);
+
+  // Test collective params build method, no attributes.
+  op = builder.create<TableGenBuildOp1>(loc, ArrayRef<Type>{i32Ty},
+                                        ArrayRef<Value>{cstI32});
+  verifyOp(std::move(op), {i32Ty}, {cstI32}, noAttrs);
+
+  // Test collective params build method no attributes, 2 inputs.
+  op = builder.create<TableGenBuildOp1>(loc, ArrayRef<Type>{i32Ty},
+                                        ArrayRef<Value>{cstI32, cstF32});
+  verifyOp(std::move(op), {i32Ty}, {cstI32, cstF32}, noAttrs);
+
+  // Test collective params build method, non-empty attributes.
+  op = builder.create<TableGenBuildOp1>(loc, ArrayRef<Type>{i32Ty},
+                                        ArrayRef<Value>{cstI32, cstF32}, attrs);
+  verifyOp(std::move(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<TableGenBuildOp3>(loc, ArrayRef<Type>{i32Ty},
+                                             ArrayRef<Type>{f32Ty},
+                                             ArrayRef<Value>{cstI32});
+  verifyOp(std::move(op), {i32Ty, f32Ty}, {cstI32}, noAttrs);
+
+  // Test collective params build method, no attributes.
+  op = builder.create<TableGenBuildOp3>(loc, ArrayRef<Type>{i32Ty, f32Ty},
+                                        ArrayRef<Value>{cstI32});
+  verifyOp(std::move(op), {i32Ty, f32Ty}, {cstI32}, noAttrs);
+
+  // Test collective params build method, with attributes.
+  op = builder.create<TableGenBuildOp3>(loc, ArrayRef<Type>{i32Ty, f32Ty},
+                                        ArrayRef<Value>{cstI32}, attrs);
+  verifyOp(std::move(op), {i32Ty, f32Ty}, {cstI32}, attrs);
+}
+
+} // namespace mlir


        


More information about the Mlir-commits mailing list