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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "gtest/gtest.h" 10 #include "flang/Optimizer/Dialect/FIROps.h" 11 #include "flang/Optimizer/Support/InitFIR.h" 12 13 struct FortranVariableTest : public testing::Test { 14 public: 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 = 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); 29 } 30 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)); 36 } 37 38 mlir::Value createShape(llvm::ArrayRef<mlir::Value> extents) { 39 return builder->create<fir::ShapeOp>(getLoc(), extents); 40 } 41 mlir::MLIRContext context; 42 std::unique_ptr<mlir::OpBuilder> builder; 43 mlir::OwningOpRef<mlir::ModuleOp> moduleOp; 44 }; 45 46 TEST_F(FortranVariableTest, SimpleScalar) { 47 mlir::Location loc = getLoc(); 48 mlir::Type eleType = mlir::Float32Type::get(&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{}); 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 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{}); 82 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); 95 } 96 97 TEST_F(FortranVariableTest, SimpleArray) { 98 mlir::Location loc = getLoc(); 99 mlir::Type eleType = mlir::Float32Type::get(&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{}); 113 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()); 124 } 125 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{}); 144 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); 156 } 157