summaryrefslogtreecommitdiff
path: root/flang/unittests
diff options
context:
space:
mode:
authorJean Perier <jperier@nvidia.com>2022-10-19 11:06:27 +0200
committerJean Perier <jperier@nvidia.com>2022-10-19 11:06:58 +0200
commita398981fb0f01473dbf9833677fe858630c38282 (patch)
tree37516b73fef3fd19a8a7db58c00398ce1bc099da /flang/unittests
parent747f27d97d230b0b3e318dd9d3815d27d1bb0652 (diff)
downloadllvm-a398981fb0f01473dbf9833677fe858630c38282.tar.gz
[flang] Add fir.declare operation
Add fir.declare operation whose purpose was described in https://reviews.llvm.org/D134285. It uses the FortranVariableInterfaceOp for most of its logic (including the verifier). The rational is that all these aspects/logic will be shared by hlfir.designate and hlfir.associate. Its codegen and lowering will be added in later patches. Differential Revision: https://reviews.llvm.org/D136181
Diffstat (limited to 'flang/unittests')
-rw-r--r--flang/unittests/Optimizer/CMakeLists.txt1
-rw-r--r--flang/unittests/Optimizer/FortranVariableTest.cpp151
2 files changed, 152 insertions, 0 deletions
diff --git a/flang/unittests/Optimizer/CMakeLists.txt b/flang/unittests/Optimizer/CMakeLists.txt
index 9f8483d8a119..e23f0cfe39ee 100644
--- a/flang/unittests/Optimizer/CMakeLists.txt
+++ b/flang/unittests/Optimizer/CMakeLists.txt
@@ -24,6 +24,7 @@ add_flang_unittest(FlangOptimizerTests
Builder/Runtime/TransformationalTest.cpp
FIRContextTest.cpp
FIRTypesTest.cpp
+ FortranVariableTest.cpp
InternalNamesTest.cpp
KindMappingTest.cpp
RTBuilder.cpp
diff --git a/flang/unittests/Optimizer/FortranVariableTest.cpp b/flang/unittests/Optimizer/FortranVariableTest.cpp
new file mode 100644
index 000000000000..ed248fc72b0a
--- /dev/null
+++ b/flang/unittests/Optimizer/FortranVariableTest.cpp
@@ -0,0 +1,151 @@
+//===- FortranVariableTest.cpp --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Support/InitFIR.h"
+
+struct FortranVariableTest : public testing::Test {
+public:
+ void SetUp() {
+ fir::support::loadDialects(context);
+ builder = std::make_unique<mlir::OpBuilder>(&context);
+ mlir::Location loc = builder->getUnknownLoc();
+
+ // Set up a Module with a dummy function operation inside.
+ // Set the insertion point in the function entry block.
+ mlir::ModuleOp mod = builder->create<mlir::ModuleOp>(loc);
+ mlir::func::FuncOp func =
+ mlir::func::FuncOp::create(loc, "fortran_variable_tests",
+ builder->getFunctionType(llvm::None, llvm::None));
+ auto *entryBlock = func.addEntryBlock();
+ mod.push_back(mod);
+ builder->setInsertionPointToStart(entryBlock);
+ }
+
+ mlir::Location getLoc() { return builder->getUnknownLoc(); }
+ mlir::Value createConstant(std::int64_t cst) {
+ mlir::Type indexType = builder->getIndexType();
+ return builder->create<mlir::arith::ConstantOp>(
+ getLoc(), indexType, builder->getIntegerAttr(indexType, cst));
+ }
+
+ mlir::Value createShape(llvm::ArrayRef<mlir::Value> extents) {
+ mlir::Type shapeType = fir::ShapeType::get(&context, extents.size());
+ return builder->create<fir::ShapeOp>(getLoc(), shapeType, extents);
+ }
+ mlir::MLIRContext context;
+ std::unique_ptr<mlir::OpBuilder> builder;
+};
+
+TEST_F(FortranVariableTest, SimpleScalar) {
+ mlir::Location loc = getLoc();
+ mlir::Type eleType = mlir::FloatType::getF32(&context);
+ mlir::Value addr = builder->create<fir::AllocaOp>(loc, eleType);
+ auto name = mlir::StringAttr::get(&context, "x");
+ auto declare = builder->create<fir::DeclareOp>(loc, addr.getType(), addr,
+ /*shape=*/mlir::Value{}, /*typeParams=*/llvm::None, name,
+ /*fortran_attrs=*/fir::FortranVariableFlagsAttr{});
+
+ fir::FortranVariableOpInterface fortranVariable = declare;
+ EXPECT_FALSE(fortranVariable.isArray());
+ EXPECT_FALSE(fortranVariable.isCharacter());
+ EXPECT_FALSE(fortranVariable.isPointer());
+ EXPECT_FALSE(fortranVariable.isAllocatable());
+ EXPECT_FALSE(fortranVariable.hasExplicitCharLen());
+ EXPECT_EQ(fortranVariable.getElementType(), eleType);
+ EXPECT_EQ(fortranVariable.getElementOrSequenceType(),
+ fortranVariable.getElementType());
+ EXPECT_NE(fortranVariable.getBase(), addr);
+ EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());
+}
+
+TEST_F(FortranVariableTest, CharacterScalar) {
+ mlir::Location loc = getLoc();
+ mlir::Type eleType = fir::CharacterType::getUnknownLen(&context, 4);
+ mlir::Value len = createConstant(42);
+ llvm::SmallVector<mlir::Value> typeParams{len};
+ mlir::Value addr = builder->create<fir::AllocaOp>(
+ loc, eleType, /*pinned=*/false, typeParams);
+ auto name = mlir::StringAttr::get(&context, "x");
+ auto declare = builder->create<fir::DeclareOp>(loc, addr.getType(), addr,
+ /*shape=*/mlir::Value{}, typeParams, name,
+ /*fortran_attrs=*/fir::FortranVariableFlagsAttr{});
+
+ fir::FortranVariableOpInterface fortranVariable = declare;
+ EXPECT_FALSE(fortranVariable.isArray());
+ EXPECT_TRUE(fortranVariable.isCharacter());
+ EXPECT_FALSE(fortranVariable.isPointer());
+ EXPECT_FALSE(fortranVariable.isAllocatable());
+ EXPECT_TRUE(fortranVariable.hasExplicitCharLen());
+ EXPECT_EQ(fortranVariable.getElementType(), eleType);
+ EXPECT_EQ(fortranVariable.getElementOrSequenceType(),
+ fortranVariable.getElementType());
+ EXPECT_NE(fortranVariable.getBase(), addr);
+ EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());
+ EXPECT_EQ(fortranVariable.getExplicitCharLen(), len);
+}
+
+TEST_F(FortranVariableTest, SimpleArray) {
+ mlir::Location loc = getLoc();
+ mlir::Type eleType = mlir::FloatType::getF32(&context);
+ llvm::SmallVector<mlir::Value> extents{
+ createConstant(10), createConstant(20), createConstant(30)};
+ fir::SequenceType::Shape typeShape(
+ extents.size(), fir::SequenceType::getUnknownExtent());
+ mlir::Type seqTy = fir::SequenceType::get(typeShape, eleType);
+ mlir::Value addr = builder->create<fir::AllocaOp>(
+ loc, seqTy, /*pinned=*/false, /*typeParams=*/llvm::None, extents);
+ mlir::Value shape = createShape(extents);
+ auto name = mlir::StringAttr::get(&context, "x");
+ auto declare = builder->create<fir::DeclareOp>(loc, addr.getType(), addr,
+ shape, /*typeParams*/ llvm::None, name,
+ /*fortran_attrs=*/fir::FortranVariableFlagsAttr{});
+
+ fir::FortranVariableOpInterface fortranVariable = declare;
+ EXPECT_TRUE(fortranVariable.isArray());
+ EXPECT_FALSE(fortranVariable.isCharacter());
+ EXPECT_FALSE(fortranVariable.isPointer());
+ EXPECT_FALSE(fortranVariable.isAllocatable());
+ EXPECT_FALSE(fortranVariable.hasExplicitCharLen());
+ EXPECT_EQ(fortranVariable.getElementType(), eleType);
+ EXPECT_EQ(fortranVariable.getElementOrSequenceType(), seqTy);
+ EXPECT_NE(fortranVariable.getBase(), addr);
+ EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());
+}
+
+TEST_F(FortranVariableTest, CharacterArray) {
+ mlir::Location loc = getLoc();
+ mlir::Type eleType = fir::CharacterType::getUnknownLen(&context, 4);
+ mlir::Value len = createConstant(42);
+ llvm::SmallVector<mlir::Value> typeParams{len};
+ llvm::SmallVector<mlir::Value> extents{
+ createConstant(10), createConstant(20), createConstant(30)};
+ fir::SequenceType::Shape typeShape(
+ extents.size(), fir::SequenceType::getUnknownExtent());
+ mlir::Type seqTy = fir::SequenceType::get(typeShape, eleType);
+ mlir::Value addr = builder->create<fir::AllocaOp>(
+ loc, seqTy, /*pinned=*/false, typeParams, extents);
+ mlir::Value shape = createShape(extents);
+ auto name = mlir::StringAttr::get(&context, "x");
+ auto declare = builder->create<fir::DeclareOp>(loc, addr.getType(), addr,
+ shape, typeParams, name,
+ /*fortran_attrs=*/fir::FortranVariableFlagsAttr{});
+
+ fir::FortranVariableOpInterface fortranVariable = declare;
+ EXPECT_TRUE(fortranVariable.isArray());
+ EXPECT_TRUE(fortranVariable.isCharacter());
+ EXPECT_FALSE(fortranVariable.isPointer());
+ EXPECT_FALSE(fortranVariable.isAllocatable());
+ EXPECT_TRUE(fortranVariable.hasExplicitCharLen());
+ EXPECT_EQ(fortranVariable.getElementType(), eleType);
+ EXPECT_EQ(fortranVariable.getElementOrSequenceType(), seqTy);
+ EXPECT_NE(fortranVariable.getBase(), addr);
+ EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());
+ EXPECT_EQ(fortranVariable.getExplicitCharLen(), len);
+}