1 //===- FortranVariableTest.cpp --------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "gtest/gtest.h"
10 #include "flang/Optimizer/Dialect/FIROps.h"
11 #include "flang/Optimizer/Support/InitFIR.h"
13 struct FortranVariableTest
: public testing::Test
{
16 fir::support::loadDialects(context
);
17 builder
= std::make_unique
<mlir::OpBuilder
>(&context
);
18 mlir::Location loc
= builder
->getUnknownLoc();
20 // Set up a Module with a dummy function operation inside.
21 // Set the insertion point in the function entry block.
22 moduleOp
= builder
->create
<mlir::ModuleOp
>(loc
);
23 builder
->setInsertionPointToStart(moduleOp
->getBody());
24 mlir::func::FuncOp func
=
25 builder
->create
<mlir::func::FuncOp
>(loc
, "fortran_variable_tests",
26 builder
->getFunctionType(std::nullopt
, std::nullopt
));
27 auto *entryBlock
= func
.addEntryBlock();
28 builder
->setInsertionPointToStart(entryBlock
);
31 mlir::Location
getLoc() { return builder
->getUnknownLoc(); }
32 mlir::Value
createConstant(std::int64_t cst
) {
33 mlir::Type indexType
= builder
->getIndexType();
34 return builder
->create
<mlir::arith::ConstantOp
>(
35 getLoc(), indexType
, builder
->getIntegerAttr(indexType
, cst
));
38 mlir::Value
createShape(llvm::ArrayRef
<mlir::Value
> extents
) {
39 return builder
->create
<fir::ShapeOp
>(getLoc(), extents
);
41 mlir::MLIRContext context
;
42 std::unique_ptr
<mlir::OpBuilder
> builder
;
43 mlir::OwningOpRef
<mlir::ModuleOp
> moduleOp
;
46 TEST_F(FortranVariableTest
, SimpleScalar
) {
47 mlir::Location loc
= getLoc();
48 mlir::Type eleType
= mlir::FloatType::getF32(&context
);
49 mlir::Value addr
= builder
->create
<fir::AllocaOp
>(loc
, eleType
);
50 auto name
= mlir::StringAttr::get(&context
, "x");
51 auto declare
= builder
->create
<fir::DeclareOp
>(loc
, addr
.getType(), addr
,
52 /*shape=*/mlir::Value
{}, /*typeParams=*/std::nullopt
,
53 /*dummy_scope=*/nullptr, name
,
54 /*fortran_attrs=*/fir::FortranVariableFlagsAttr
{},
55 /*data_attr=*/cuf::DataAttributeAttr
{});
57 fir::FortranVariableOpInterface fortranVariable
= declare
;
58 EXPECT_FALSE(fortranVariable
.isArray());
59 EXPECT_FALSE(fortranVariable
.isCharacter());
60 EXPECT_FALSE(fortranVariable
.isPointer());
61 EXPECT_FALSE(fortranVariable
.isAllocatable());
62 EXPECT_FALSE(fortranVariable
.hasExplicitCharLen());
63 EXPECT_EQ(fortranVariable
.getElementType(), eleType
);
64 EXPECT_EQ(fortranVariable
.getElementOrSequenceType(),
65 fortranVariable
.getElementType());
66 EXPECT_NE(fortranVariable
.getBase(), addr
);
67 EXPECT_EQ(fortranVariable
.getBase().getType(), addr
.getType());
70 TEST_F(FortranVariableTest
, CharacterScalar
) {
71 mlir::Location loc
= getLoc();
72 mlir::Type eleType
= fir::CharacterType::getUnknownLen(&context
, 4);
73 mlir::Value len
= createConstant(42);
74 llvm::SmallVector
<mlir::Value
> typeParams
{len
};
75 mlir::Value addr
= builder
->create
<fir::AllocaOp
>(
76 loc
, eleType
, /*pinned=*/false, typeParams
);
77 auto name
= mlir::StringAttr::get(&context
, "x");
78 auto declare
= builder
->create
<fir::DeclareOp
>(loc
, addr
.getType(), addr
,
79 /*shape=*/mlir::Value
{}, typeParams
, /*dummy_scope=*/nullptr, name
,
80 /*fortran_attrs=*/fir::FortranVariableFlagsAttr
{},
81 /*data_attr=*/cuf::DataAttributeAttr
{});
83 fir::FortranVariableOpInterface fortranVariable
= declare
;
84 EXPECT_FALSE(fortranVariable
.isArray());
85 EXPECT_TRUE(fortranVariable
.isCharacter());
86 EXPECT_FALSE(fortranVariable
.isPointer());
87 EXPECT_FALSE(fortranVariable
.isAllocatable());
88 EXPECT_TRUE(fortranVariable
.hasExplicitCharLen());
89 EXPECT_EQ(fortranVariable
.getElementType(), eleType
);
90 EXPECT_EQ(fortranVariable
.getElementOrSequenceType(),
91 fortranVariable
.getElementType());
92 EXPECT_NE(fortranVariable
.getBase(), addr
);
93 EXPECT_EQ(fortranVariable
.getBase().getType(), addr
.getType());
94 EXPECT_EQ(fortranVariable
.getExplicitCharLen(), len
);
97 TEST_F(FortranVariableTest
, SimpleArray
) {
98 mlir::Location loc
= getLoc();
99 mlir::Type eleType
= mlir::FloatType::getF32(&context
);
100 llvm::SmallVector
<mlir::Value
> extents
{
101 createConstant(10), createConstant(20), createConstant(30)};
102 fir::SequenceType::Shape
typeShape(
103 extents
.size(), fir::SequenceType::getUnknownExtent());
104 mlir::Type seqTy
= fir::SequenceType::get(typeShape
, eleType
);
105 mlir::Value addr
= builder
->create
<fir::AllocaOp
>(
106 loc
, seqTy
, /*pinned=*/false, /*typeParams=*/std::nullopt
, extents
);
107 mlir::Value shape
= createShape(extents
);
108 auto name
= mlir::StringAttr::get(&context
, "x");
109 auto declare
= builder
->create
<fir::DeclareOp
>(loc
, addr
.getType(), addr
,
110 shape
, /*typeParams*/ std::nullopt
, /*dummy_scope=*/nullptr, name
,
111 /*fortran_attrs=*/fir::FortranVariableFlagsAttr
{},
112 /*data_attr=*/cuf::DataAttributeAttr
{});
114 fir::FortranVariableOpInterface fortranVariable
= declare
;
115 EXPECT_TRUE(fortranVariable
.isArray());
116 EXPECT_FALSE(fortranVariable
.isCharacter());
117 EXPECT_FALSE(fortranVariable
.isPointer());
118 EXPECT_FALSE(fortranVariable
.isAllocatable());
119 EXPECT_FALSE(fortranVariable
.hasExplicitCharLen());
120 EXPECT_EQ(fortranVariable
.getElementType(), eleType
);
121 EXPECT_EQ(fortranVariable
.getElementOrSequenceType(), seqTy
);
122 EXPECT_NE(fortranVariable
.getBase(), addr
);
123 EXPECT_EQ(fortranVariable
.getBase().getType(), addr
.getType());
126 TEST_F(FortranVariableTest
, CharacterArray
) {
127 mlir::Location loc
= getLoc();
128 mlir::Type eleType
= fir::CharacterType::getUnknownLen(&context
, 4);
129 mlir::Value len
= createConstant(42);
130 llvm::SmallVector
<mlir::Value
> typeParams
{len
};
131 llvm::SmallVector
<mlir::Value
> extents
{
132 createConstant(10), createConstant(20), createConstant(30)};
133 fir::SequenceType::Shape
typeShape(
134 extents
.size(), fir::SequenceType::getUnknownExtent());
135 mlir::Type seqTy
= fir::SequenceType::get(typeShape
, eleType
);
136 mlir::Value addr
= builder
->create
<fir::AllocaOp
>(
137 loc
, seqTy
, /*pinned=*/false, typeParams
, extents
);
138 mlir::Value shape
= createShape(extents
);
139 auto name
= mlir::StringAttr::get(&context
, "x");
140 auto declare
= builder
->create
<fir::DeclareOp
>(loc
, addr
.getType(), addr
,
141 shape
, typeParams
, /*dummy_scope=*/nullptr, name
,
142 /*fortran_attrs=*/fir::FortranVariableFlagsAttr
{},
143 /*data_attr=*/cuf::DataAttributeAttr
{});
145 fir::FortranVariableOpInterface fortranVariable
= declare
;
146 EXPECT_TRUE(fortranVariable
.isArray());
147 EXPECT_TRUE(fortranVariable
.isCharacter());
148 EXPECT_FALSE(fortranVariable
.isPointer());
149 EXPECT_FALSE(fortranVariable
.isAllocatable());
150 EXPECT_TRUE(fortranVariable
.hasExplicitCharLen());
151 EXPECT_EQ(fortranVariable
.getElementType(), eleType
);
152 EXPECT_EQ(fortranVariable
.getElementOrSequenceType(), seqTy
);
153 EXPECT_NE(fortranVariable
.getBase(), addr
);
154 EXPECT_EQ(fortranVariable
.getBase().getType(), addr
.getType());
155 EXPECT_EQ(fortranVariable
.getExplicitCharLen(), len
);