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