diff options
author | Jean Perier <jperier@nvidia.com> | 2022-10-19 11:06:27 +0200 |
---|---|---|
committer | Jean Perier <jperier@nvidia.com> | 2022-10-19 11:06:58 +0200 |
commit | a398981fb0f01473dbf9833677fe858630c38282 (patch) | |
tree | 37516b73fef3fd19a8a7db58c00398ce1bc099da /flang/unittests | |
parent | 747f27d97d230b0b3e318dd9d3815d27d1bb0652 (diff) | |
download | llvm-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.txt | 1 | ||||
-rw-r--r-- | flang/unittests/Optimizer/FortranVariableTest.cpp | 151 |
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); +} |