1 //===- FIRBuilderTest.cpp -- FIRBuilder unit tests ------------------------===// 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 "flang/Optimizer/Builder/FIRBuilder.h" 10 #include "gtest/gtest.h" 11 #include "flang/Optimizer/Builder/BoxValue.h" 12 #include "flang/Optimizer/Support/InitFIR.h" 13 #include "flang/Optimizer/Support/KindMapping.h" 14 15 using namespace mlir; 16 17 struct FIRBuilderTest : public testing::Test { 18 public: 19 void SetUp() override { 20 fir::support::loadDialects(context); 21 22 llvm::ArrayRef<fir::KindTy> defs; 23 fir::KindMapping kindMap(&context, defs); 24 mlir::OpBuilder builder(&context); 25 auto loc = builder.getUnknownLoc(); 26 27 // Set up a Module with a dummy function operation inside. 28 // Set the insertion point in the function entry block. 29 mlir::ModuleOp mod = builder.create<mlir::ModuleOp>(loc); 30 mlir::func::FuncOp func = mlir::func::FuncOp::create( 31 loc, "func1", builder.getFunctionType(llvm::None, llvm::None)); 32 auto *entryBlock = func.addEntryBlock(); 33 mod.push_back(mod); 34 builder.setInsertionPointToStart(entryBlock); 35 36 firBuilder = std::make_unique<fir::FirOpBuilder>(mod, kindMap); 37 } 38 39 fir::FirOpBuilder &getBuilder() { return *firBuilder; } 40 41 mlir::MLIRContext context; 42 std::unique_ptr<fir::FirOpBuilder> firBuilder; 43 }; 44 45 static arith::CmpIOp createCondition(fir::FirOpBuilder &builder) { 46 auto loc = builder.getUnknownLoc(); 47 auto zero1 = builder.createIntegerConstant(loc, builder.getIndexType(), 0); 48 auto zero2 = builder.createIntegerConstant(loc, builder.getIndexType(), 0); 49 return builder.create<arith::CmpIOp>( 50 loc, arith::CmpIPredicate::eq, zero1, zero2); 51 } 52 53 static void checkIntegerConstant(mlir::Value value, mlir::Type ty, int64_t v) { 54 EXPECT_TRUE(mlir::isa<mlir::arith::ConstantOp>(value.getDefiningOp())); 55 auto cstOp = dyn_cast<mlir::arith::ConstantOp>(value.getDefiningOp()); 56 EXPECT_EQ(ty, cstOp.getType()); 57 auto valueAttr = cstOp.getValue().dyn_cast_or_null<IntegerAttr>(); 58 EXPECT_EQ(v, valueAttr.getInt()); 59 } 60 61 //===----------------------------------------------------------------------===// 62 // IfBuilder tests 63 //===----------------------------------------------------------------------===// 64 65 TEST_F(FIRBuilderTest, genIfThen) { 66 auto builder = getBuilder(); 67 auto loc = builder.getUnknownLoc(); 68 auto cdt = createCondition(builder); 69 auto ifBuilder = builder.genIfThen(loc, cdt); 70 EXPECT_FALSE(ifBuilder.getIfOp().getThenRegion().empty()); 71 EXPECT_TRUE(ifBuilder.getIfOp().getElseRegion().empty()); 72 } 73 74 TEST_F(FIRBuilderTest, genIfThenElse) { 75 auto builder = getBuilder(); 76 auto loc = builder.getUnknownLoc(); 77 auto cdt = createCondition(builder); 78 auto ifBuilder = builder.genIfThenElse(loc, cdt); 79 EXPECT_FALSE(ifBuilder.getIfOp().getThenRegion().empty()); 80 EXPECT_FALSE(ifBuilder.getIfOp().getElseRegion().empty()); 81 } 82 83 TEST_F(FIRBuilderTest, genIfWithThen) { 84 auto builder = getBuilder(); 85 auto loc = builder.getUnknownLoc(); 86 auto cdt = createCondition(builder); 87 auto ifBuilder = builder.genIfOp(loc, {}, cdt, false); 88 EXPECT_FALSE(ifBuilder.getIfOp().getThenRegion().empty()); 89 EXPECT_TRUE(ifBuilder.getIfOp().getElseRegion().empty()); 90 } 91 92 TEST_F(FIRBuilderTest, genIfWithThenAndElse) { 93 auto builder = getBuilder(); 94 auto loc = builder.getUnknownLoc(); 95 auto cdt = createCondition(builder); 96 auto ifBuilder = builder.genIfOp(loc, {}, cdt, true); 97 EXPECT_FALSE(ifBuilder.getIfOp().getThenRegion().empty()); 98 EXPECT_FALSE(ifBuilder.getIfOp().getElseRegion().empty()); 99 } 100 101 //===----------------------------------------------------------------------===// 102 // Helper functions tests 103 //===----------------------------------------------------------------------===// 104 105 TEST_F(FIRBuilderTest, genIsNotNull) { 106 auto builder = getBuilder(); 107 auto loc = builder.getUnknownLoc(); 108 auto dummyValue = 109 builder.createIntegerConstant(loc, builder.getIndexType(), 0); 110 auto res = builder.genIsNotNull(loc, dummyValue); 111 EXPECT_TRUE(mlir::isa<arith::CmpIOp>(res.getDefiningOp())); 112 auto cmpOp = dyn_cast<arith::CmpIOp>(res.getDefiningOp()); 113 EXPECT_EQ(arith::CmpIPredicate::ne, cmpOp.getPredicate()); 114 } 115 116 TEST_F(FIRBuilderTest, genIsNull) { 117 auto builder = getBuilder(); 118 auto loc = builder.getUnknownLoc(); 119 auto dummyValue = 120 builder.createIntegerConstant(loc, builder.getIndexType(), 0); 121 auto res = builder.genIsNull(loc, dummyValue); 122 EXPECT_TRUE(mlir::isa<arith::CmpIOp>(res.getDefiningOp())); 123 auto cmpOp = dyn_cast<arith::CmpIOp>(res.getDefiningOp()); 124 EXPECT_EQ(arith::CmpIPredicate::eq, cmpOp.getPredicate()); 125 } 126 127 TEST_F(FIRBuilderTest, createZeroConstant) { 128 auto builder = getBuilder(); 129 auto loc = builder.getUnknownLoc(); 130 131 auto cst = builder.createNullConstant(loc); 132 EXPECT_TRUE(mlir::isa<fir::ZeroOp>(cst.getDefiningOp())); 133 auto zeroOp = dyn_cast<fir::ZeroOp>(cst.getDefiningOp()); 134 EXPECT_EQ(fir::ReferenceType::get(builder.getNoneType()), 135 zeroOp.getResult().getType()); 136 auto idxTy = builder.getIndexType(); 137 138 cst = builder.createNullConstant(loc, idxTy); 139 EXPECT_TRUE(mlir::isa<fir::ZeroOp>(cst.getDefiningOp())); 140 zeroOp = dyn_cast<fir::ZeroOp>(cst.getDefiningOp()); 141 EXPECT_EQ(builder.getIndexType(), zeroOp.getResult().getType()); 142 } 143 144 TEST_F(FIRBuilderTest, createRealZeroConstant) { 145 auto builder = getBuilder(); 146 auto ctx = builder.getContext(); 147 auto loc = builder.getUnknownLoc(); 148 auto realTy = mlir::FloatType::getF64(ctx); 149 auto cst = builder.createRealZeroConstant(loc, realTy); 150 EXPECT_TRUE(mlir::isa<arith::ConstantOp>(cst.getDefiningOp())); 151 auto cstOp = dyn_cast<arith::ConstantOp>(cst.getDefiningOp()); 152 EXPECT_EQ(realTy, cstOp.getType()); 153 EXPECT_EQ( 154 0u, cstOp.getValue().cast<FloatAttr>().getValue().convertToDouble()); 155 } 156 157 TEST_F(FIRBuilderTest, createBool) { 158 auto builder = getBuilder(); 159 auto loc = builder.getUnknownLoc(); 160 auto b = builder.createBool(loc, false); 161 checkIntegerConstant(b, builder.getIntegerType(1), 0); 162 } 163 164 TEST_F(FIRBuilderTest, getVarLenSeqTy) { 165 auto builder = getBuilder(); 166 auto ty = builder.getVarLenSeqTy(builder.getI64Type()); 167 EXPECT_TRUE(ty.isa<fir::SequenceType>()); 168 fir::SequenceType seqTy = ty.dyn_cast<fir::SequenceType>(); 169 EXPECT_EQ(1u, seqTy.getDimension()); 170 EXPECT_TRUE(fir::unwrapSequenceType(ty).isInteger(64)); 171 } 172 173 TEST_F(FIRBuilderTest, getNamedFunction) { 174 auto builder = getBuilder(); 175 auto func2 = builder.getNamedFunction("func2"); 176 EXPECT_EQ(nullptr, func2); 177 auto loc = builder.getUnknownLoc(); 178 func2 = builder.createFunction( 179 loc, "func2", builder.getFunctionType(llvm::None, llvm::None)); 180 auto func2query = builder.getNamedFunction("func2"); 181 EXPECT_EQ(func2, func2query); 182 } 183 184 TEST_F(FIRBuilderTest, createGlobal1) { 185 auto builder = getBuilder(); 186 auto loc = builder.getUnknownLoc(); 187 auto i64Type = IntegerType::get(builder.getContext(), 64); 188 auto global = builder.createGlobal( 189 loc, i64Type, "global1", builder.createInternalLinkage(), {}, true); 190 EXPECT_TRUE(mlir::isa<fir::GlobalOp>(global)); 191 EXPECT_EQ("global1", global.getSymName()); 192 EXPECT_TRUE(global.getConstant().hasValue()); 193 EXPECT_EQ(i64Type, global.getType()); 194 EXPECT_TRUE(global.getLinkName().hasValue()); 195 EXPECT_EQ(builder.createInternalLinkage().getValue(), 196 global.getLinkName().getValue()); 197 EXPECT_FALSE(global.getInitVal().hasValue()); 198 199 auto g1 = builder.getNamedGlobal("global1"); 200 EXPECT_EQ(global, g1); 201 auto g2 = builder.getNamedGlobal("global7"); 202 EXPECT_EQ(nullptr, g2); 203 auto g3 = builder.getNamedGlobal(""); 204 EXPECT_EQ(nullptr, g3); 205 } 206 207 TEST_F(FIRBuilderTest, createGlobal2) { 208 auto builder = getBuilder(); 209 auto loc = builder.getUnknownLoc(); 210 auto i32Type = IntegerType::get(builder.getContext(), 32); 211 auto attr = builder.getIntegerAttr(i32Type, 16); 212 auto global = builder.createGlobal( 213 loc, i32Type, "global2", builder.createLinkOnceLinkage(), attr, false); 214 EXPECT_TRUE(mlir::isa<fir::GlobalOp>(global)); 215 EXPECT_EQ("global2", global.getSymName()); 216 EXPECT_FALSE(global.getConstant().hasValue()); 217 EXPECT_EQ(i32Type, global.getType()); 218 EXPECT_TRUE(global.getInitVal().hasValue()); 219 EXPECT_TRUE(global.getInitVal().getValue().isa<mlir::IntegerAttr>()); 220 EXPECT_EQ( 221 16, global.getInitVal().getValue().cast<mlir::IntegerAttr>().getValue()); 222 EXPECT_TRUE(global.getLinkName().hasValue()); 223 EXPECT_EQ(builder.createLinkOnceLinkage().getValue(), 224 global.getLinkName().getValue()); 225 } 226 227 TEST_F(FIRBuilderTest, uniqueCFIdent) { 228 auto str1 = fir::factory::uniqueCGIdent("", "func1"); 229 EXPECT_EQ("_QQ.66756E6331", str1); 230 str1 = fir::factory::uniqueCGIdent("", ""); 231 EXPECT_EQ("_QQ.", str1); 232 str1 = fir::factory::uniqueCGIdent("pr", "func1"); 233 EXPECT_EQ("_QQpr.66756E6331", str1); 234 str1 = fir::factory::uniqueCGIdent( 235 "", "longnamemorethan32characterneedshashing"); 236 EXPECT_EQ("_QQ.c22a886b2f30ea8c064ef1178377fc31", str1); 237 str1 = fir::factory::uniqueCGIdent( 238 "pr", "longnamemorethan32characterneedshashing"); 239 EXPECT_EQ("_QQpr.c22a886b2f30ea8c064ef1178377fc31", str1); 240 } 241 242 TEST_F(FIRBuilderTest, locationToLineNo) { 243 auto builder = getBuilder(); 244 auto loc = mlir::FileLineColLoc::get(builder.getStringAttr("file1"), 10, 5); 245 mlir::Value line = 246 fir::factory::locationToLineNo(builder, loc, builder.getI64Type()); 247 checkIntegerConstant(line, builder.getI64Type(), 10); 248 line = fir::factory::locationToLineNo( 249 builder, builder.getUnknownLoc(), builder.getI64Type()); 250 checkIntegerConstant(line, builder.getI64Type(), 0); 251 } 252 253 TEST_F(FIRBuilderTest, hasDynamicSize) { 254 auto builder = getBuilder(); 255 auto type = fir::CharacterType::get(builder.getContext(), 1, 16); 256 EXPECT_FALSE(fir::hasDynamicSize(type)); 257 EXPECT_TRUE(fir::SequenceType::getUnknownExtent()); 258 auto seqTy = builder.getVarLenSeqTy(builder.getI64Type(), 10); 259 EXPECT_TRUE(fir::hasDynamicSize(seqTy)); 260 EXPECT_FALSE(fir::hasDynamicSize(builder.getI64Type())); 261 } 262 263 TEST_F(FIRBuilderTest, locationToFilename) { 264 auto builder = getBuilder(); 265 auto loc = 266 mlir::FileLineColLoc::get(builder.getStringAttr("file1.f90"), 10, 5); 267 mlir::Value locToFile = fir::factory::locationToFilename(builder, loc); 268 auto addrOp = dyn_cast<fir::AddrOfOp>(locToFile.getDefiningOp()); 269 auto symbol = addrOp.getSymbol().getRootReference().getValue(); 270 auto global = builder.getNamedGlobal(symbol); 271 auto stringLitOps = global.getRegion().front().getOps<fir::StringLitOp>(); 272 EXPECT_TRUE(llvm::hasSingleElement(stringLitOps)); 273 for (auto stringLit : stringLitOps) { 274 EXPECT_EQ(10, stringLit.getSize().cast<mlir::IntegerAttr>().getValue()); 275 EXPECT_TRUE(stringLit.getValue().isa<StringAttr>()); 276 EXPECT_EQ(0, 277 strcmp("file1.f90\0", 278 stringLit.getValue() 279 .dyn_cast<StringAttr>() 280 .getValue() 281 .str() 282 .c_str())); 283 } 284 } 285 286 TEST_F(FIRBuilderTest, createStringLitOp) { 287 auto builder = getBuilder(); 288 llvm::StringRef data("mystringlitdata"); 289 auto loc = builder.getUnknownLoc(); 290 auto op = builder.createStringLitOp(loc, data); 291 EXPECT_EQ(15, op.getSize().cast<mlir::IntegerAttr>().getValue()); 292 EXPECT_TRUE(op.getValue().isa<StringAttr>()); 293 EXPECT_EQ(data, op.getValue().dyn_cast<StringAttr>().getValue()); 294 } 295 296 TEST_F(FIRBuilderTest, createStringLiteral) { 297 auto builder = getBuilder(); 298 auto loc = builder.getUnknownLoc(); 299 llvm::StringRef strValue("onestringliteral"); 300 auto strLit = fir::factory::createStringLiteral(builder, loc, strValue); 301 EXPECT_EQ(0u, strLit.rank()); 302 EXPECT_TRUE(strLit.getCharBox() != nullptr); 303 auto *charBox = strLit.getCharBox(); 304 EXPECT_FALSE(fir::isArray(*charBox)); 305 checkIntegerConstant(charBox->getLen(), builder.getCharacterLengthType(), 16); 306 auto generalGetLen = fir::getLen(strLit); 307 checkIntegerConstant(generalGetLen, builder.getCharacterLengthType(), 16); 308 auto addr = charBox->getBuffer(); 309 EXPECT_TRUE(mlir::isa<fir::AddrOfOp>(addr.getDefiningOp())); 310 auto addrOp = dyn_cast<fir::AddrOfOp>(addr.getDefiningOp()); 311 auto symbol = addrOp.getSymbol().getRootReference().getValue(); 312 auto global = builder.getNamedGlobal(symbol); 313 EXPECT_EQ(builder.createLinkOnceLinkage().getValue(), 314 global.getLinkName().getValue()); 315 EXPECT_EQ(fir::CharacterType::get(builder.getContext(), 1, strValue.size()), 316 global.getType()); 317 318 auto stringLitOps = global.getRegion().front().getOps<fir::StringLitOp>(); 319 EXPECT_TRUE(llvm::hasSingleElement(stringLitOps)); 320 for (auto stringLit : stringLitOps) { 321 EXPECT_EQ(16, stringLit.getSize().cast<mlir::IntegerAttr>().getValue()); 322 EXPECT_TRUE(stringLit.getValue().isa<StringAttr>()); 323 EXPECT_EQ(strValue, stringLit.getValue().dyn_cast<StringAttr>().getValue()); 324 } 325 } 326 327 TEST_F(FIRBuilderTest, allocateLocal) { 328 auto builder = getBuilder(); 329 auto loc = builder.getUnknownLoc(); 330 llvm::StringRef varName = "var1"; 331 auto var = builder.allocateLocal( 332 loc, builder.getI64Type(), "", varName, {}, {}, false); 333 EXPECT_TRUE(mlir::isa<fir::AllocaOp>(var.getDefiningOp())); 334 auto allocaOp = dyn_cast<fir::AllocaOp>(var.getDefiningOp()); 335 EXPECT_EQ(builder.getI64Type(), allocaOp.getInType()); 336 EXPECT_TRUE(allocaOp.getBindcName().hasValue()); 337 EXPECT_EQ(varName, allocaOp.getBindcName().getValue()); 338 EXPECT_FALSE(allocaOp.getUniqName().hasValue()); 339 EXPECT_FALSE(allocaOp.getPinned()); 340 EXPECT_EQ(0u, allocaOp.getTypeparams().size()); 341 EXPECT_EQ(0u, allocaOp.getShape().size()); 342 } 343 344 static void checkShapeOp(mlir::Value shape, mlir::Value c10, mlir::Value c100) { 345 EXPECT_TRUE(mlir::isa<fir::ShapeOp>(shape.getDefiningOp())); 346 fir::ShapeOp op = dyn_cast<fir::ShapeOp>(shape.getDefiningOp()); 347 auto shapeTy = op.getType().dyn_cast<fir::ShapeType>(); 348 EXPECT_EQ(2u, shapeTy.getRank()); 349 EXPECT_EQ(2u, op.getExtents().size()); 350 EXPECT_EQ(c10, op.getExtents()[0]); 351 EXPECT_EQ(c100, op.getExtents()[1]); 352 } 353 354 TEST_F(FIRBuilderTest, genShapeWithExtents) { 355 auto builder = getBuilder(); 356 auto loc = builder.getUnknownLoc(); 357 auto c10 = builder.createIntegerConstant(loc, builder.getI64Type(), 10); 358 auto c100 = builder.createIntegerConstant(loc, builder.getI64Type(), 100); 359 llvm::SmallVector<mlir::Value> extents = {c10, c100}; 360 auto shape = builder.genShape(loc, extents); 361 checkShapeOp(shape, c10, c100); 362 } 363 364 TEST_F(FIRBuilderTest, genShapeWithExtentsAndShapeShift) { 365 auto builder = getBuilder(); 366 auto loc = builder.getUnknownLoc(); 367 auto c10 = builder.createIntegerConstant(loc, builder.getI64Type(), 10); 368 auto c100 = builder.createIntegerConstant(loc, builder.getI64Type(), 100); 369 auto c1 = builder.createIntegerConstant(loc, builder.getI64Type(), 100); 370 llvm::SmallVector<mlir::Value> shifts = {c1, c1}; 371 llvm::SmallVector<mlir::Value> extents = {c10, c100}; 372 auto shape = builder.genShape(loc, shifts, extents); 373 EXPECT_TRUE(mlir::isa<fir::ShapeShiftOp>(shape.getDefiningOp())); 374 fir::ShapeShiftOp op = dyn_cast<fir::ShapeShiftOp>(shape.getDefiningOp()); 375 auto shapeTy = op.getType().dyn_cast<fir::ShapeShiftType>(); 376 EXPECT_EQ(2u, shapeTy.getRank()); 377 EXPECT_EQ(2u, op.getExtents().size()); 378 EXPECT_EQ(2u, op.getOrigins().size()); 379 } 380 381 TEST_F(FIRBuilderTest, genShapeWithAbstractArrayBox) { 382 auto builder = getBuilder(); 383 auto loc = builder.getUnknownLoc(); 384 auto c10 = builder.createIntegerConstant(loc, builder.getI64Type(), 10); 385 auto c100 = builder.createIntegerConstant(loc, builder.getI64Type(), 100); 386 llvm::SmallVector<mlir::Value> extents = {c10, c100}; 387 fir::AbstractArrayBox aab(extents, {}); 388 EXPECT_TRUE(aab.lboundsAllOne()); 389 auto shape = builder.genShape(loc, aab); 390 checkShapeOp(shape, c10, c100); 391 } 392 393 TEST_F(FIRBuilderTest, readCharLen) { 394 auto builder = getBuilder(); 395 auto loc = builder.getUnknownLoc(); 396 llvm::StringRef strValue("length"); 397 auto strLit = fir::factory::createStringLiteral(builder, loc, strValue); 398 auto len = fir::factory::readCharLen(builder, loc, strLit); 399 EXPECT_EQ(strLit.getCharBox()->getLen(), len); 400 } 401 402 TEST_F(FIRBuilderTest, getExtents) { 403 auto builder = getBuilder(); 404 auto loc = builder.getUnknownLoc(); 405 llvm::StringRef strValue("length"); 406 auto strLit = fir::factory::createStringLiteral(builder, loc, strValue); 407 auto ext = fir::factory::getExtents(builder, loc, strLit); 408 EXPECT_EQ(0u, ext.size()); 409 auto c10 = builder.createIntegerConstant(loc, builder.getI64Type(), 10); 410 auto c100 = builder.createIntegerConstant(loc, builder.getI64Type(), 100); 411 llvm::SmallVector<mlir::Value> extents = {c10, c100}; 412 fir::SequenceType::Shape shape(2, fir::SequenceType::getUnknownExtent()); 413 auto arrayTy = fir::SequenceType::get(shape, builder.getI64Type()); 414 mlir::Value array = builder.create<fir::UndefOp>(loc, arrayTy); 415 fir::ArrayBoxValue aab(array, extents, {}); 416 fir::ExtendedValue ex(aab); 417 auto readExtents = fir::factory::getExtents(builder, loc, ex); 418 EXPECT_EQ(2u, readExtents.size()); 419 } 420 421 TEST_F(FIRBuilderTest, createZeroValue) { 422 auto builder = getBuilder(); 423 auto loc = builder.getUnknownLoc(); 424 425 mlir::Type i64Ty = mlir::IntegerType::get(builder.getContext(), 64); 426 mlir::Value zeroInt = fir::factory::createZeroValue(builder, loc, i64Ty); 427 EXPECT_TRUE(zeroInt.getType() == i64Ty); 428 auto cst = 429 mlir::dyn_cast_or_null<mlir::arith::ConstantOp>(zeroInt.getDefiningOp()); 430 EXPECT_TRUE(cst); 431 auto intAttr = cst.getValue().dyn_cast<mlir::IntegerAttr>(); 432 EXPECT_TRUE(intAttr && intAttr.getInt() == 0); 433 434 mlir::Type f32Ty = mlir::FloatType::getF32(builder.getContext()); 435 mlir::Value zeroFloat = fir::factory::createZeroValue(builder, loc, f32Ty); 436 EXPECT_TRUE(zeroFloat.getType() == f32Ty); 437 auto cst2 = mlir::dyn_cast_or_null<mlir::arith::ConstantOp>( 438 zeroFloat.getDefiningOp()); 439 EXPECT_TRUE(cst2); 440 auto floatAttr = cst2.getValue().dyn_cast<mlir::FloatAttr>(); 441 EXPECT_TRUE(floatAttr && floatAttr.getValueAsDouble() == 0.); 442 443 mlir::Type boolTy = mlir::IntegerType::get(builder.getContext(), 1); 444 mlir::Value flaseBool = fir::factory::createZeroValue(builder, loc, boolTy); 445 EXPECT_TRUE(flaseBool.getType() == boolTy); 446 auto cst3 = mlir::dyn_cast_or_null<mlir::arith::ConstantOp>( 447 flaseBool.getDefiningOp()); 448 EXPECT_TRUE(cst3); 449 auto intAttr2 = cst.getValue().dyn_cast<mlir::IntegerAttr>(); 450 EXPECT_TRUE(intAttr2 && intAttr2.getInt() == 0); 451 } 452 453 TEST_F(FIRBuilderTest, getBaseTypeOf) { 454 auto builder = getBuilder(); 455 auto loc = builder.getUnknownLoc(); 456 457 auto makeExv = [&](mlir::Type elementType, mlir::Type arrayType) 458 -> std::tuple<llvm::SmallVector<fir::ExtendedValue, 4>, 459 llvm::SmallVector<fir::ExtendedValue, 4>> { 460 auto ptrTyArray = fir::PointerType::get(arrayType); 461 auto ptrTyScalar = fir::PointerType::get(elementType); 462 auto ptrBoxTyArray = fir::BoxType::get(ptrTyArray); 463 auto ptrBoxTyScalar = fir::BoxType::get(ptrTyScalar); 464 auto boxRefTyArray = fir::ReferenceType::get(ptrBoxTyArray); 465 auto boxRefTyScalar = fir::ReferenceType::get(ptrBoxTyScalar); 466 auto boxTyArray = fir::BoxType::get(arrayType); 467 auto boxTyScalar = fir::BoxType::get(elementType); 468 469 auto ptrValArray = builder.create<fir::UndefOp>(loc, ptrTyArray); 470 auto ptrValScalar = builder.create<fir::UndefOp>(loc, ptrTyScalar); 471 auto boxRefValArray = builder.create<fir::UndefOp>(loc, boxRefTyArray); 472 auto boxRefValScalar = builder.create<fir::UndefOp>(loc, boxRefTyScalar); 473 auto boxValArray = builder.create<fir::UndefOp>(loc, boxTyArray); 474 auto boxValScalar = builder.create<fir::UndefOp>(loc, boxTyScalar); 475 476 llvm::SmallVector<fir::ExtendedValue, 4> scalars; 477 scalars.emplace_back(fir::UnboxedValue(ptrValScalar)); 478 scalars.emplace_back(fir::BoxValue(boxValScalar)); 479 scalars.emplace_back( 480 fir::MutableBoxValue(boxRefValScalar, mlir::ValueRange(), {})); 481 482 llvm::SmallVector<fir::ExtendedValue, 4> arrays; 483 auto extent = builder.create<fir::UndefOp>(loc, builder.getIndexType()); 484 llvm::SmallVector<mlir::Value> extents( 485 arrayType.dyn_cast<fir::SequenceType>().getDimension(), 486 extent.getResult()); 487 arrays.emplace_back(fir::ArrayBoxValue(ptrValArray, extents)); 488 arrays.emplace_back(fir::BoxValue(boxValArray)); 489 arrays.emplace_back( 490 fir::MutableBoxValue(boxRefValArray, mlir::ValueRange(), {})); 491 return {scalars, arrays}; 492 }; 493 494 auto f32Ty = mlir::FloatType::getF32(builder.getContext()); 495 mlir::Type f32SeqTy = builder.getVarLenSeqTy(f32Ty); 496 auto [f32Scalars, f32Arrays] = makeExv(f32Ty, f32SeqTy); 497 for (const auto &scalar : f32Scalars) { 498 EXPECT_EQ(fir::getBaseTypeOf(scalar), f32Ty); 499 EXPECT_EQ(fir::getElementTypeOf(scalar), f32Ty); 500 EXPECT_FALSE(fir::isDerivedWithLengthParameters(scalar)); 501 } 502 for (const auto &array : f32Arrays) { 503 EXPECT_EQ(fir::getBaseTypeOf(array), f32SeqTy); 504 EXPECT_EQ(fir::getElementTypeOf(array), f32Ty); 505 EXPECT_FALSE(fir::isDerivedWithLengthParameters(array)); 506 } 507 508 auto derivedWithLengthTy = 509 fir::RecordType::get(builder.getContext(), "derived_test"); 510 511 llvm::SmallVector<std::pair<std::string, mlir::Type>> parameters; 512 llvm::SmallVector<std::pair<std::string, mlir::Type>> components; 513 parameters.emplace_back("p1", builder.getI64Type()); 514 components.emplace_back("c1", f32Ty); 515 derivedWithLengthTy.finalize(parameters, components); 516 mlir::Type derivedWithLengthSeqTy = 517 builder.getVarLenSeqTy(derivedWithLengthTy); 518 auto [derivedWithLengthScalars, derivedWithLengthArrays] = 519 makeExv(derivedWithLengthTy, derivedWithLengthSeqTy); 520 for (const auto &scalar : derivedWithLengthScalars) { 521 EXPECT_EQ(fir::getBaseTypeOf(scalar), derivedWithLengthTy); 522 EXPECT_EQ(fir::getElementTypeOf(scalar), derivedWithLengthTy); 523 EXPECT_TRUE(fir::isDerivedWithLengthParameters(scalar)); 524 } 525 for (const auto &array : derivedWithLengthArrays) { 526 EXPECT_EQ(fir::getBaseTypeOf(array), derivedWithLengthSeqTy); 527 EXPECT_EQ(fir::getElementTypeOf(array), derivedWithLengthTy); 528 EXPECT_TRUE(fir::isDerivedWithLengthParameters(array)); 529 } 530 } 531