163 lines · cpp
1//===- FortranVariableTest.cpp --------------------------------------------===//2//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "gtest/gtest.h"10#include "flang/Optimizer/Dialect/FIROps.h"11#include "flang/Optimizer/Support/InitFIR.h"12 13struct FortranVariableTest : public testing::Test {14public:15 void SetUp() {16 fir::support::loadDialects(context);17 builder = std::make_unique<mlir::OpBuilder>(&context);18 mlir::Location loc = builder->getUnknownLoc();19 20 // Set up a Module with a dummy function operation inside.21 // Set the insertion point in the function entry block.22 moduleOp = mlir::ModuleOp::create(*builder, loc);23 builder->setInsertionPointToStart(moduleOp->getBody());24 mlir::func::FuncOp func = mlir::func::FuncOp::create(*builder, loc,25 "fortran_variable_tests", builder->getFunctionType({}, {}));26 auto *entryBlock = func.addEntryBlock();27 builder->setInsertionPointToStart(entryBlock);28 }29 30 mlir::Location getLoc() { return builder->getUnknownLoc(); }31 mlir::Value createConstant(std::int64_t cst) {32 mlir::Type indexType = builder->getIndexType();33 return mlir::arith::ConstantOp::create(34 *builder, getLoc(), indexType, builder->getIntegerAttr(indexType, cst));35 }36 37 mlir::Value createShape(llvm::ArrayRef<mlir::Value> extents) {38 return fir::ShapeOp::create(*builder, getLoc(), extents);39 }40 mlir::MLIRContext context;41 std::unique_ptr<mlir::OpBuilder> builder;42 mlir::OwningOpRef<mlir::ModuleOp> moduleOp;43};44 45TEST_F(FortranVariableTest, SimpleScalar) {46 mlir::Location loc = getLoc();47 mlir::Type eleType = mlir::Float32Type::get(&context);48 mlir::Value addr = fir::AllocaOp::create(*builder, loc, eleType);49 auto name = mlir::StringAttr::get(&context, "x");50 auto declare = fir::DeclareOp::create(*builder, loc, addr.getType(), addr,51 /*shape=*/mlir::Value{}, /*typeParams=*/mlir::ValueRange{},52 /*dummy_scope=*/nullptr, /*storage=*/nullptr, /*storage_offset=*/0, name,53 /*fortran_attrs=*/fir::FortranVariableFlagsAttr{},54 /*data_attr=*/cuf::DataAttributeAttr{},55 /*dummy_arg_no=*/mlir::IntegerAttr{});56 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());68}69 70TEST_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 = fir::AllocaOp::create(76 *builder, loc, eleType, /*pinned=*/false, typeParams);77 auto name = mlir::StringAttr::get(&context, "x");78 auto declare = fir::DeclareOp::create(*builder, loc, addr.getType(), addr,79 /*shape=*/mlir::Value{}, typeParams, /*dummy_scope=*/nullptr,80 /*storage=*/nullptr, /*storage_offset=*/0, name,81 /*fortran_attrs=*/fir::FortranVariableFlagsAttr{},82 /*data_attr=*/cuf::DataAttributeAttr{},83 /*dummy_arg_no=*/mlir::IntegerAttr{});84 85 fir::FortranVariableOpInterface fortranVariable = declare;86 EXPECT_FALSE(fortranVariable.isArray());87 EXPECT_TRUE(fortranVariable.isCharacter());88 EXPECT_FALSE(fortranVariable.isPointer());89 EXPECT_FALSE(fortranVariable.isAllocatable());90 EXPECT_TRUE(fortranVariable.hasExplicitCharLen());91 EXPECT_EQ(fortranVariable.getElementType(), eleType);92 EXPECT_EQ(fortranVariable.getElementOrSequenceType(),93 fortranVariable.getElementType());94 EXPECT_NE(fortranVariable.getBase(), addr);95 EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());96 EXPECT_EQ(fortranVariable.getExplicitCharLen(), len);97}98 99TEST_F(FortranVariableTest, SimpleArray) {100 mlir::Location loc = getLoc();101 mlir::Type eleType = mlir::Float32Type::get(&context);102 llvm::SmallVector<mlir::Value> extents{103 createConstant(10), createConstant(20), createConstant(30)};104 fir::SequenceType::Shape typeShape(105 extents.size(), fir::SequenceType::getUnknownExtent());106 mlir::Type seqTy = fir::SequenceType::get(typeShape, eleType);107 mlir::Value addr = fir::AllocaOp::create(*builder, loc, seqTy,108 /*pinned=*/false, /*typeParams=*/mlir::ValueRange{}, extents);109 mlir::Value shape = createShape(extents);110 auto name = mlir::StringAttr::get(&context, "x");111 auto declare = fir::DeclareOp::create(*builder, loc, addr.getType(), addr,112 shape, /*typeParams=*/mlir::ValueRange{}, /*dummy_scope=*/nullptr,113 /*storage=*/nullptr, /*storage_offset=*/0, name,114 /*fortran_attrs=*/fir::FortranVariableFlagsAttr{},115 /*data_attr=*/cuf::DataAttributeAttr{},116 /*dummy_arg_no=*/mlir::IntegerAttr{});117 118 fir::FortranVariableOpInterface fortranVariable = declare;119 EXPECT_TRUE(fortranVariable.isArray());120 EXPECT_FALSE(fortranVariable.isCharacter());121 EXPECT_FALSE(fortranVariable.isPointer());122 EXPECT_FALSE(fortranVariable.isAllocatable());123 EXPECT_FALSE(fortranVariable.hasExplicitCharLen());124 EXPECT_EQ(fortranVariable.getElementType(), eleType);125 EXPECT_EQ(fortranVariable.getElementOrSequenceType(), seqTy);126 EXPECT_NE(fortranVariable.getBase(), addr);127 EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());128}129 130TEST_F(FortranVariableTest, CharacterArray) {131 mlir::Location loc = getLoc();132 mlir::Type eleType = fir::CharacterType::getUnknownLen(&context, 4);133 mlir::Value len = createConstant(42);134 llvm::SmallVector<mlir::Value> typeParams{len};135 llvm::SmallVector<mlir::Value> extents{136 createConstant(10), createConstant(20), createConstant(30)};137 fir::SequenceType::Shape typeShape(138 extents.size(), fir::SequenceType::getUnknownExtent());139 mlir::Type seqTy = fir::SequenceType::get(typeShape, eleType);140 mlir::Value addr = fir::AllocaOp::create(141 *builder, loc, seqTy, /*pinned=*/false, typeParams, extents);142 mlir::Value shape = createShape(extents);143 auto name = mlir::StringAttr::get(&context, "x");144 auto declare = fir::DeclareOp::create(*builder, loc, addr.getType(), addr,145 shape, typeParams, /*dummy_scope=*/nullptr, /*storage=*/nullptr,146 /*storage_offset=*/0, name,147 /*fortran_attrs=*/fir::FortranVariableFlagsAttr{},148 /*data_attr=*/cuf::DataAttributeAttr{},149 /*dummy_arg_no=*/mlir::IntegerAttr{});150 151 fir::FortranVariableOpInterface fortranVariable = declare;152 EXPECT_TRUE(fortranVariable.isArray());153 EXPECT_TRUE(fortranVariable.isCharacter());154 EXPECT_FALSE(fortranVariable.isPointer());155 EXPECT_FALSE(fortranVariable.isAllocatable());156 EXPECT_TRUE(fortranVariable.hasExplicitCharLen());157 EXPECT_EQ(fortranVariable.getElementType(), eleType);158 EXPECT_EQ(fortranVariable.getElementOrSequenceType(), seqTy);159 EXPECT_NE(fortranVariable.getBase(), addr);160 EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());161 EXPECT_EQ(fortranVariable.getExplicitCharLen(), len);162}163