xref: /llvm-project/flang/unittests/Optimizer/FortranVariableTest.cpp (revision f023da12d12635f5fba436e825cbfc999e28e623)
1a398981fSJean Perier //===- FortranVariableTest.cpp --------------------------------------------===//
2a398981fSJean Perier //
3a398981fSJean Perier // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4a398981fSJean Perier // See https://llvm.org/LICENSE.txt for license information.
5a398981fSJean Perier // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a398981fSJean Perier //
7a398981fSJean Perier //===----------------------------------------------------------------------===//
8a398981fSJean Perier 
9a398981fSJean Perier #include "gtest/gtest.h"
10a398981fSJean Perier #include "flang/Optimizer/Dialect/FIROps.h"
11a398981fSJean Perier #include "flang/Optimizer/Support/InitFIR.h"
12a398981fSJean Perier 
13a398981fSJean Perier struct FortranVariableTest : public testing::Test {
14a398981fSJean Perier public:
15a398981fSJean Perier   void SetUp() {
16a398981fSJean Perier     fir::support::loadDialects(context);
17a398981fSJean Perier     builder = std::make_unique<mlir::OpBuilder>(&context);
18a398981fSJean Perier     mlir::Location loc = builder->getUnknownLoc();
19a398981fSJean Perier 
20a398981fSJean Perier     // Set up a Module with a dummy function operation inside.
21a398981fSJean Perier     // Set the insertion point in the function entry block.
22c870632eSMatthias Springer     moduleOp = builder->create<mlir::ModuleOp>(loc);
23c870632eSMatthias Springer     builder->setInsertionPointToStart(moduleOp->getBody());
24a398981fSJean Perier     mlir::func::FuncOp func =
25c870632eSMatthias Springer         builder->create<mlir::func::FuncOp>(loc, "fortran_variable_tests",
2663b63c3dSKazu Hirata             builder->getFunctionType(std::nullopt, std::nullopt));
27a398981fSJean Perier     auto *entryBlock = func.addEntryBlock();
28a398981fSJean Perier     builder->setInsertionPointToStart(entryBlock);
29a398981fSJean Perier   }
30a398981fSJean Perier 
31a398981fSJean Perier   mlir::Location getLoc() { return builder->getUnknownLoc(); }
32a398981fSJean Perier   mlir::Value createConstant(std::int64_t cst) {
33a398981fSJean Perier     mlir::Type indexType = builder->getIndexType();
34a398981fSJean Perier     return builder->create<mlir::arith::ConstantOp>(
35a398981fSJean Perier         getLoc(), indexType, builder->getIntegerAttr(indexType, cst));
36a398981fSJean Perier   }
37a398981fSJean Perier 
38a398981fSJean Perier   mlir::Value createShape(llvm::ArrayRef<mlir::Value> extents) {
39b22fa865SJean Perier     return builder->create<fir::ShapeOp>(getLoc(), extents);
40a398981fSJean Perier   }
41a398981fSJean Perier   mlir::MLIRContext context;
42a398981fSJean Perier   std::unique_ptr<mlir::OpBuilder> builder;
43c870632eSMatthias Springer   mlir::OwningOpRef<mlir::ModuleOp> moduleOp;
44a398981fSJean Perier };
45a398981fSJean Perier 
46a398981fSJean Perier TEST_F(FortranVariableTest, SimpleScalar) {
47a398981fSJean Perier   mlir::Location loc = getLoc();
48*f023da12SMatthias Springer   mlir::Type eleType = mlir::Float32Type::get(&context);
49a398981fSJean Perier   mlir::Value addr = builder->create<fir::AllocaOp>(loc, eleType);
50a398981fSJean Perier   auto name = mlir::StringAttr::get(&context, "x");
51a398981fSJean Perier   auto declare = builder->create<fir::DeclareOp>(loc, addr.getType(), addr,
52986f832cSSlava Zakharin       /*shape=*/mlir::Value{}, /*typeParams=*/std::nullopt,
53986f832cSSlava Zakharin       /*dummy_scope=*/nullptr, name,
54abc4f74dSValentin Clement (バレンタイン クレメン)       /*fortran_attrs=*/fir::FortranVariableFlagsAttr{},
5545daa4fdSValentin Clement (バレンタイン クレメン)       /*data_attr=*/cuf::DataAttributeAttr{});
56a398981fSJean Perier 
57a398981fSJean Perier   fir::FortranVariableOpInterface fortranVariable = declare;
58a398981fSJean Perier   EXPECT_FALSE(fortranVariable.isArray());
59a398981fSJean Perier   EXPECT_FALSE(fortranVariable.isCharacter());
60a398981fSJean Perier   EXPECT_FALSE(fortranVariable.isPointer());
61a398981fSJean Perier   EXPECT_FALSE(fortranVariable.isAllocatable());
62a398981fSJean Perier   EXPECT_FALSE(fortranVariable.hasExplicitCharLen());
63a398981fSJean Perier   EXPECT_EQ(fortranVariable.getElementType(), eleType);
64a398981fSJean Perier   EXPECT_EQ(fortranVariable.getElementOrSequenceType(),
65a398981fSJean Perier       fortranVariable.getElementType());
66a398981fSJean Perier   EXPECT_NE(fortranVariable.getBase(), addr);
67a398981fSJean Perier   EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());
68a398981fSJean Perier }
69a398981fSJean Perier 
70a398981fSJean Perier TEST_F(FortranVariableTest, CharacterScalar) {
71a398981fSJean Perier   mlir::Location loc = getLoc();
72a398981fSJean Perier   mlir::Type eleType = fir::CharacterType::getUnknownLen(&context, 4);
73a398981fSJean Perier   mlir::Value len = createConstant(42);
74a398981fSJean Perier   llvm::SmallVector<mlir::Value> typeParams{len};
75a398981fSJean Perier   mlir::Value addr = builder->create<fir::AllocaOp>(
76a398981fSJean Perier       loc, eleType, /*pinned=*/false, typeParams);
77a398981fSJean Perier   auto name = mlir::StringAttr::get(&context, "x");
78a398981fSJean Perier   auto declare = builder->create<fir::DeclareOp>(loc, addr.getType(), addr,
79986f832cSSlava Zakharin       /*shape=*/mlir::Value{}, typeParams, /*dummy_scope=*/nullptr, name,
80abc4f74dSValentin Clement (バレンタイン クレメン)       /*fortran_attrs=*/fir::FortranVariableFlagsAttr{},
8145daa4fdSValentin Clement (バレンタイン クレメン)       /*data_attr=*/cuf::DataAttributeAttr{});
82a398981fSJean Perier 
83a398981fSJean Perier   fir::FortranVariableOpInterface fortranVariable = declare;
84a398981fSJean Perier   EXPECT_FALSE(fortranVariable.isArray());
85a398981fSJean Perier   EXPECT_TRUE(fortranVariable.isCharacter());
86a398981fSJean Perier   EXPECT_FALSE(fortranVariable.isPointer());
87a398981fSJean Perier   EXPECT_FALSE(fortranVariable.isAllocatable());
88a398981fSJean Perier   EXPECT_TRUE(fortranVariable.hasExplicitCharLen());
89a398981fSJean Perier   EXPECT_EQ(fortranVariable.getElementType(), eleType);
90a398981fSJean Perier   EXPECT_EQ(fortranVariable.getElementOrSequenceType(),
91a398981fSJean Perier       fortranVariable.getElementType());
92a398981fSJean Perier   EXPECT_NE(fortranVariable.getBase(), addr);
93a398981fSJean Perier   EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());
94a398981fSJean Perier   EXPECT_EQ(fortranVariable.getExplicitCharLen(), len);
95a398981fSJean Perier }
96a398981fSJean Perier 
97a398981fSJean Perier TEST_F(FortranVariableTest, SimpleArray) {
98a398981fSJean Perier   mlir::Location loc = getLoc();
99*f023da12SMatthias Springer   mlir::Type eleType = mlir::Float32Type::get(&context);
100a398981fSJean Perier   llvm::SmallVector<mlir::Value> extents{
101a398981fSJean Perier       createConstant(10), createConstant(20), createConstant(30)};
102a398981fSJean Perier   fir::SequenceType::Shape typeShape(
103a398981fSJean Perier       extents.size(), fir::SequenceType::getUnknownExtent());
104a398981fSJean Perier   mlir::Type seqTy = fir::SequenceType::get(typeShape, eleType);
105a398981fSJean Perier   mlir::Value addr = builder->create<fir::AllocaOp>(
10663b63c3dSKazu Hirata       loc, seqTy, /*pinned=*/false, /*typeParams=*/std::nullopt, extents);
107a398981fSJean Perier   mlir::Value shape = createShape(extents);
108a398981fSJean Perier   auto name = mlir::StringAttr::get(&context, "x");
109a398981fSJean Perier   auto declare = builder->create<fir::DeclareOp>(loc, addr.getType(), addr,
110986f832cSSlava Zakharin       shape, /*typeParams*/ std::nullopt, /*dummy_scope=*/nullptr, name,
111abc4f74dSValentin Clement (バレンタイン クレメン)       /*fortran_attrs=*/fir::FortranVariableFlagsAttr{},
11245daa4fdSValentin Clement (バレンタイン クレメン)       /*data_attr=*/cuf::DataAttributeAttr{});
113a398981fSJean Perier 
114a398981fSJean Perier   fir::FortranVariableOpInterface fortranVariable = declare;
115a398981fSJean Perier   EXPECT_TRUE(fortranVariable.isArray());
116a398981fSJean Perier   EXPECT_FALSE(fortranVariable.isCharacter());
117a398981fSJean Perier   EXPECT_FALSE(fortranVariable.isPointer());
118a398981fSJean Perier   EXPECT_FALSE(fortranVariable.isAllocatable());
119a398981fSJean Perier   EXPECT_FALSE(fortranVariable.hasExplicitCharLen());
120a398981fSJean Perier   EXPECT_EQ(fortranVariable.getElementType(), eleType);
121a398981fSJean Perier   EXPECT_EQ(fortranVariable.getElementOrSequenceType(), seqTy);
122a398981fSJean Perier   EXPECT_NE(fortranVariable.getBase(), addr);
123a398981fSJean Perier   EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());
124a398981fSJean Perier }
125a398981fSJean Perier 
126a398981fSJean Perier TEST_F(FortranVariableTest, CharacterArray) {
127a398981fSJean Perier   mlir::Location loc = getLoc();
128a398981fSJean Perier   mlir::Type eleType = fir::CharacterType::getUnknownLen(&context, 4);
129a398981fSJean Perier   mlir::Value len = createConstant(42);
130a398981fSJean Perier   llvm::SmallVector<mlir::Value> typeParams{len};
131a398981fSJean Perier   llvm::SmallVector<mlir::Value> extents{
132a398981fSJean Perier       createConstant(10), createConstant(20), createConstant(30)};
133a398981fSJean Perier   fir::SequenceType::Shape typeShape(
134a398981fSJean Perier       extents.size(), fir::SequenceType::getUnknownExtent());
135a398981fSJean Perier   mlir::Type seqTy = fir::SequenceType::get(typeShape, eleType);
136a398981fSJean Perier   mlir::Value addr = builder->create<fir::AllocaOp>(
137a398981fSJean Perier       loc, seqTy, /*pinned=*/false, typeParams, extents);
138a398981fSJean Perier   mlir::Value shape = createShape(extents);
139a398981fSJean Perier   auto name = mlir::StringAttr::get(&context, "x");
140a398981fSJean Perier   auto declare = builder->create<fir::DeclareOp>(loc, addr.getType(), addr,
141986f832cSSlava Zakharin       shape, typeParams, /*dummy_scope=*/nullptr, name,
142abc4f74dSValentin Clement (バレンタイン クレメン)       /*fortran_attrs=*/fir::FortranVariableFlagsAttr{},
14345daa4fdSValentin Clement (バレンタイン クレメン)       /*data_attr=*/cuf::DataAttributeAttr{});
144a398981fSJean Perier 
145a398981fSJean Perier   fir::FortranVariableOpInterface fortranVariable = declare;
146a398981fSJean Perier   EXPECT_TRUE(fortranVariable.isArray());
147a398981fSJean Perier   EXPECT_TRUE(fortranVariable.isCharacter());
148a398981fSJean Perier   EXPECT_FALSE(fortranVariable.isPointer());
149a398981fSJean Perier   EXPECT_FALSE(fortranVariable.isAllocatable());
150a398981fSJean Perier   EXPECT_TRUE(fortranVariable.hasExplicitCharLen());
151a398981fSJean Perier   EXPECT_EQ(fortranVariable.getElementType(), eleType);
152a398981fSJean Perier   EXPECT_EQ(fortranVariable.getElementOrSequenceType(), seqTy);
153a398981fSJean Perier   EXPECT_NE(fortranVariable.getBase(), addr);
154a398981fSJean Perier   EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());
155a398981fSJean Perier   EXPECT_EQ(fortranVariable.getExplicitCharLen(), len);
156a398981fSJean Perier }
157