Files
clang-p2996/flang/unittests/Optimizer/Builder/FIRBuilderTest.cpp
River Riddle 3655069234 [mlir] Move the Builtin FuncOp to the Func dialect
This commit moves FuncOp out of the builtin dialect, and into the Func
dialect. This move has been planned in some capacity from the moment
we made FuncOp an operation (years ago). This commit handles the
functional aspects of the move, but various aspects are left untouched
to ease migration: func::FuncOp is re-exported into mlir to reduce
the actual API churn, the assembly format still accepts the unqualified
`func`. These temporary measures will remain for a little while to
simplify migration before being removed.

Differential Revision: https://reviews.llvm.org/D121266
2022-03-16 17:07:03 -07:00

531 lines
22 KiB
C++

//===- FIRBuilderTest.cpp -- FIRBuilder unit tests ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "gtest/gtest.h"
#include "flang/Optimizer/Builder/BoxValue.h"
#include "flang/Optimizer/Support/InitFIR.h"
#include "flang/Optimizer/Support/KindMapping.h"
using namespace mlir;
struct FIRBuilderTest : public testing::Test {
public:
void SetUp() override {
fir::support::loadDialects(context);
llvm::ArrayRef<fir::KindTy> defs;
fir::KindMapping kindMap(&context, defs);
mlir::OpBuilder builder(&context);
auto loc = builder.getUnknownLoc();
// Set up a Module with a dummy function operation inside.
// Set the insertion point in the function entry block.
mlir::ModuleOp mod = builder.create<mlir::ModuleOp>(loc);
mlir::FuncOp func = mlir::FuncOp::create(
loc, "func1", builder.getFunctionType(llvm::None, llvm::None));
auto *entryBlock = func.addEntryBlock();
mod.push_back(mod);
builder.setInsertionPointToStart(entryBlock);
firBuilder = std::make_unique<fir::FirOpBuilder>(mod, kindMap);
}
fir::FirOpBuilder &getBuilder() { return *firBuilder; }
mlir::MLIRContext context;
std::unique_ptr<fir::FirOpBuilder> firBuilder;
};
static arith::CmpIOp createCondition(fir::FirOpBuilder &builder) {
auto loc = builder.getUnknownLoc();
auto zero1 = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
auto zero2 = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
return builder.create<arith::CmpIOp>(
loc, arith::CmpIPredicate::eq, zero1, zero2);
}
static void checkIntegerConstant(mlir::Value value, mlir::Type ty, int64_t v) {
EXPECT_TRUE(mlir::isa<mlir::arith::ConstantOp>(value.getDefiningOp()));
auto cstOp = dyn_cast<mlir::arith::ConstantOp>(value.getDefiningOp());
EXPECT_EQ(ty, cstOp.getType());
auto valueAttr = cstOp.getValue().dyn_cast_or_null<IntegerAttr>();
EXPECT_EQ(v, valueAttr.getInt());
}
//===----------------------------------------------------------------------===//
// IfBuilder tests
//===----------------------------------------------------------------------===//
TEST_F(FIRBuilderTest, genIfThen) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
auto cdt = createCondition(builder);
auto ifBuilder = builder.genIfThen(loc, cdt);
EXPECT_FALSE(ifBuilder.getIfOp().getThenRegion().empty());
EXPECT_TRUE(ifBuilder.getIfOp().getElseRegion().empty());
}
TEST_F(FIRBuilderTest, genIfThenElse) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
auto cdt = createCondition(builder);
auto ifBuilder = builder.genIfThenElse(loc, cdt);
EXPECT_FALSE(ifBuilder.getIfOp().getThenRegion().empty());
EXPECT_FALSE(ifBuilder.getIfOp().getElseRegion().empty());
}
TEST_F(FIRBuilderTest, genIfWithThen) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
auto cdt = createCondition(builder);
auto ifBuilder = builder.genIfOp(loc, {}, cdt, false);
EXPECT_FALSE(ifBuilder.getIfOp().getThenRegion().empty());
EXPECT_TRUE(ifBuilder.getIfOp().getElseRegion().empty());
}
TEST_F(FIRBuilderTest, genIfWithThenAndElse) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
auto cdt = createCondition(builder);
auto ifBuilder = builder.genIfOp(loc, {}, cdt, true);
EXPECT_FALSE(ifBuilder.getIfOp().getThenRegion().empty());
EXPECT_FALSE(ifBuilder.getIfOp().getElseRegion().empty());
}
//===----------------------------------------------------------------------===//
// Helper functions tests
//===----------------------------------------------------------------------===//
TEST_F(FIRBuilderTest, genIsNotNull) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
auto dummyValue =
builder.createIntegerConstant(loc, builder.getIndexType(), 0);
auto res = builder.genIsNotNull(loc, dummyValue);
EXPECT_TRUE(mlir::isa<arith::CmpIOp>(res.getDefiningOp()));
auto cmpOp = dyn_cast<arith::CmpIOp>(res.getDefiningOp());
EXPECT_EQ(arith::CmpIPredicate::ne, cmpOp.getPredicate());
}
TEST_F(FIRBuilderTest, genIsNull) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
auto dummyValue =
builder.createIntegerConstant(loc, builder.getIndexType(), 0);
auto res = builder.genIsNull(loc, dummyValue);
EXPECT_TRUE(mlir::isa<arith::CmpIOp>(res.getDefiningOp()));
auto cmpOp = dyn_cast<arith::CmpIOp>(res.getDefiningOp());
EXPECT_EQ(arith::CmpIPredicate::eq, cmpOp.getPredicate());
}
TEST_F(FIRBuilderTest, createZeroConstant) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
auto cst = builder.createNullConstant(loc);
EXPECT_TRUE(mlir::isa<fir::ZeroOp>(cst.getDefiningOp()));
auto zeroOp = dyn_cast<fir::ZeroOp>(cst.getDefiningOp());
EXPECT_EQ(fir::ReferenceType::get(builder.getNoneType()),
zeroOp.getResult().getType());
auto idxTy = builder.getIndexType();
cst = builder.createNullConstant(loc, idxTy);
EXPECT_TRUE(mlir::isa<fir::ZeroOp>(cst.getDefiningOp()));
zeroOp = dyn_cast<fir::ZeroOp>(cst.getDefiningOp());
EXPECT_EQ(builder.getIndexType(), zeroOp.getResult().getType());
}
TEST_F(FIRBuilderTest, createRealZeroConstant) {
auto builder = getBuilder();
auto ctx = builder.getContext();
auto loc = builder.getUnknownLoc();
auto realTy = mlir::FloatType::getF64(ctx);
auto cst = builder.createRealZeroConstant(loc, realTy);
EXPECT_TRUE(mlir::isa<arith::ConstantOp>(cst.getDefiningOp()));
auto cstOp = dyn_cast<arith::ConstantOp>(cst.getDefiningOp());
EXPECT_EQ(realTy, cstOp.getType());
EXPECT_EQ(
0u, cstOp.getValue().cast<FloatAttr>().getValue().convertToDouble());
}
TEST_F(FIRBuilderTest, createBool) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
auto b = builder.createBool(loc, false);
checkIntegerConstant(b, builder.getIntegerType(1), 0);
}
TEST_F(FIRBuilderTest, getVarLenSeqTy) {
auto builder = getBuilder();
auto ty = builder.getVarLenSeqTy(builder.getI64Type());
EXPECT_TRUE(ty.isa<fir::SequenceType>());
fir::SequenceType seqTy = ty.dyn_cast<fir::SequenceType>();
EXPECT_EQ(1u, seqTy.getDimension());
EXPECT_TRUE(fir::unwrapSequenceType(ty).isInteger(64));
}
TEST_F(FIRBuilderTest, getNamedFunction) {
auto builder = getBuilder();
auto func2 = builder.getNamedFunction("func2");
EXPECT_EQ(nullptr, func2);
auto loc = builder.getUnknownLoc();
func2 = builder.createFunction(
loc, "func2", builder.getFunctionType(llvm::None, llvm::None));
auto func2query = builder.getNamedFunction("func2");
EXPECT_EQ(func2, func2query);
}
TEST_F(FIRBuilderTest, createGlobal1) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
auto i64Type = IntegerType::get(builder.getContext(), 64);
auto global = builder.createGlobal(
loc, i64Type, "global1", builder.createInternalLinkage(), {}, true);
EXPECT_TRUE(mlir::isa<fir::GlobalOp>(global));
EXPECT_EQ("global1", global.getSymName());
EXPECT_TRUE(global.getConstant().hasValue());
EXPECT_EQ(i64Type, global.getType());
EXPECT_TRUE(global.getLinkName().hasValue());
EXPECT_EQ(builder.createInternalLinkage().getValue(),
global.getLinkName().getValue());
EXPECT_FALSE(global.getInitVal().hasValue());
auto g1 = builder.getNamedGlobal("global1");
EXPECT_EQ(global, g1);
auto g2 = builder.getNamedGlobal("global7");
EXPECT_EQ(nullptr, g2);
auto g3 = builder.getNamedGlobal("");
EXPECT_EQ(nullptr, g3);
}
TEST_F(FIRBuilderTest, createGlobal2) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
auto i32Type = IntegerType::get(builder.getContext(), 32);
auto attr = builder.getIntegerAttr(i32Type, 16);
auto global = builder.createGlobal(
loc, i32Type, "global2", builder.createLinkOnceLinkage(), attr, false);
EXPECT_TRUE(mlir::isa<fir::GlobalOp>(global));
EXPECT_EQ("global2", global.getSymName());
EXPECT_FALSE(global.getConstant().hasValue());
EXPECT_EQ(i32Type, global.getType());
EXPECT_TRUE(global.getInitVal().hasValue());
EXPECT_TRUE(global.getInitVal().getValue().isa<mlir::IntegerAttr>());
EXPECT_EQ(
16, global.getInitVal().getValue().cast<mlir::IntegerAttr>().getValue());
EXPECT_TRUE(global.getLinkName().hasValue());
EXPECT_EQ(builder.createLinkOnceLinkage().getValue(),
global.getLinkName().getValue());
}
TEST_F(FIRBuilderTest, uniqueCFIdent) {
auto str1 = fir::factory::uniqueCGIdent("", "func1");
EXPECT_EQ("_QQ.66756E6331", str1);
str1 = fir::factory::uniqueCGIdent("", "");
EXPECT_EQ("_QQ.", str1);
str1 = fir::factory::uniqueCGIdent("pr", "func1");
EXPECT_EQ("_QQpr.66756E6331", str1);
str1 = fir::factory::uniqueCGIdent(
"", "longnamemorethan32characterneedshashing");
EXPECT_EQ("_QQ.c22a886b2f30ea8c064ef1178377fc31", str1);
str1 = fir::factory::uniqueCGIdent(
"pr", "longnamemorethan32characterneedshashing");
EXPECT_EQ("_QQpr.c22a886b2f30ea8c064ef1178377fc31", str1);
}
TEST_F(FIRBuilderTest, locationToLineNo) {
auto builder = getBuilder();
auto loc = mlir::FileLineColLoc::get(builder.getStringAttr("file1"), 10, 5);
mlir::Value line =
fir::factory::locationToLineNo(builder, loc, builder.getI64Type());
checkIntegerConstant(line, builder.getI64Type(), 10);
line = fir::factory::locationToLineNo(
builder, builder.getUnknownLoc(), builder.getI64Type());
checkIntegerConstant(line, builder.getI64Type(), 0);
}
TEST_F(FIRBuilderTest, hasDynamicSize) {
auto builder = getBuilder();
auto type = fir::CharacterType::get(builder.getContext(), 1, 16);
EXPECT_FALSE(fir::hasDynamicSize(type));
EXPECT_TRUE(fir::SequenceType::getUnknownExtent());
auto seqTy = builder.getVarLenSeqTy(builder.getI64Type(), 10);
EXPECT_TRUE(fir::hasDynamicSize(seqTy));
EXPECT_FALSE(fir::hasDynamicSize(builder.getI64Type()));
}
TEST_F(FIRBuilderTest, locationToFilename) {
auto builder = getBuilder();
auto loc =
mlir::FileLineColLoc::get(builder.getStringAttr("file1.f90"), 10, 5);
mlir::Value locToFile = fir::factory::locationToFilename(builder, loc);
auto addrOp = dyn_cast<fir::AddrOfOp>(locToFile.getDefiningOp());
auto symbol = addrOp.getSymbol().getRootReference().getValue();
auto global = builder.getNamedGlobal(symbol);
auto stringLitOps = global.getRegion().front().getOps<fir::StringLitOp>();
EXPECT_TRUE(llvm::hasSingleElement(stringLitOps));
for (auto stringLit : stringLitOps) {
EXPECT_EQ(10, stringLit.getSize().cast<mlir::IntegerAttr>().getValue());
EXPECT_TRUE(stringLit.getValue().isa<StringAttr>());
EXPECT_EQ(0,
strcmp("file1.f90\0",
stringLit.getValue()
.dyn_cast<StringAttr>()
.getValue()
.str()
.c_str()));
}
}
TEST_F(FIRBuilderTest, createStringLitOp) {
auto builder = getBuilder();
llvm::StringRef data("mystringlitdata");
auto loc = builder.getUnknownLoc();
auto op = builder.createStringLitOp(loc, data);
EXPECT_EQ(15, op.getSize().cast<mlir::IntegerAttr>().getValue());
EXPECT_TRUE(op.getValue().isa<StringAttr>());
EXPECT_EQ(data, op.getValue().dyn_cast<StringAttr>().getValue());
}
TEST_F(FIRBuilderTest, createStringLiteral) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
llvm::StringRef strValue("onestringliteral");
auto strLit = fir::factory::createStringLiteral(builder, loc, strValue);
EXPECT_EQ(0u, strLit.rank());
EXPECT_TRUE(strLit.getCharBox() != nullptr);
auto *charBox = strLit.getCharBox();
EXPECT_FALSE(fir::isArray(*charBox));
checkIntegerConstant(charBox->getLen(), builder.getCharacterLengthType(), 16);
auto generalGetLen = fir::getLen(strLit);
checkIntegerConstant(generalGetLen, builder.getCharacterLengthType(), 16);
auto addr = charBox->getBuffer();
EXPECT_TRUE(mlir::isa<fir::AddrOfOp>(addr.getDefiningOp()));
auto addrOp = dyn_cast<fir::AddrOfOp>(addr.getDefiningOp());
auto symbol = addrOp.getSymbol().getRootReference().getValue();
auto global = builder.getNamedGlobal(symbol);
EXPECT_EQ(builder.createLinkOnceLinkage().getValue(),
global.getLinkName().getValue());
EXPECT_EQ(fir::CharacterType::get(builder.getContext(), 1, strValue.size()),
global.getType());
auto stringLitOps = global.getRegion().front().getOps<fir::StringLitOp>();
EXPECT_TRUE(llvm::hasSingleElement(stringLitOps));
for (auto stringLit : stringLitOps) {
EXPECT_EQ(16, stringLit.getSize().cast<mlir::IntegerAttr>().getValue());
EXPECT_TRUE(stringLit.getValue().isa<StringAttr>());
EXPECT_EQ(strValue, stringLit.getValue().dyn_cast<StringAttr>().getValue());
}
}
TEST_F(FIRBuilderTest, allocateLocal) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
llvm::StringRef varName = "var1";
auto var = builder.allocateLocal(
loc, builder.getI64Type(), "", varName, {}, {}, false);
EXPECT_TRUE(mlir::isa<fir::AllocaOp>(var.getDefiningOp()));
auto allocaOp = dyn_cast<fir::AllocaOp>(var.getDefiningOp());
EXPECT_EQ(builder.getI64Type(), allocaOp.getInType());
EXPECT_TRUE(allocaOp.getBindcName().hasValue());
EXPECT_EQ(varName, allocaOp.getBindcName().getValue());
EXPECT_FALSE(allocaOp.getUniqName().hasValue());
EXPECT_FALSE(allocaOp.getPinned());
EXPECT_EQ(0u, allocaOp.getTypeparams().size());
EXPECT_EQ(0u, allocaOp.getShape().size());
}
static void checkShapeOp(mlir::Value shape, mlir::Value c10, mlir::Value c100) {
EXPECT_TRUE(mlir::isa<fir::ShapeOp>(shape.getDefiningOp()));
fir::ShapeOp op = dyn_cast<fir::ShapeOp>(shape.getDefiningOp());
auto shapeTy = op.getType().dyn_cast<fir::ShapeType>();
EXPECT_EQ(2u, shapeTy.getRank());
EXPECT_EQ(2u, op.getExtents().size());
EXPECT_EQ(c10, op.getExtents()[0]);
EXPECT_EQ(c100, op.getExtents()[1]);
}
TEST_F(FIRBuilderTest, genShapeWithExtents) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
auto c10 = builder.createIntegerConstant(loc, builder.getI64Type(), 10);
auto c100 = builder.createIntegerConstant(loc, builder.getI64Type(), 100);
llvm::SmallVector<mlir::Value> extents = {c10, c100};
auto shape = builder.genShape(loc, extents);
checkShapeOp(shape, c10, c100);
}
TEST_F(FIRBuilderTest, genShapeWithExtentsAndShapeShift) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
auto c10 = builder.createIntegerConstant(loc, builder.getI64Type(), 10);
auto c100 = builder.createIntegerConstant(loc, builder.getI64Type(), 100);
auto c1 = builder.createIntegerConstant(loc, builder.getI64Type(), 100);
llvm::SmallVector<mlir::Value> shifts = {c1, c1};
llvm::SmallVector<mlir::Value> extents = {c10, c100};
auto shape = builder.genShape(loc, shifts, extents);
EXPECT_TRUE(mlir::isa<fir::ShapeShiftOp>(shape.getDefiningOp()));
fir::ShapeShiftOp op = dyn_cast<fir::ShapeShiftOp>(shape.getDefiningOp());
auto shapeTy = op.getType().dyn_cast<fir::ShapeShiftType>();
EXPECT_EQ(2u, shapeTy.getRank());
EXPECT_EQ(2u, op.getExtents().size());
EXPECT_EQ(2u, op.getOrigins().size());
}
TEST_F(FIRBuilderTest, genShapeWithAbstractArrayBox) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
auto c10 = builder.createIntegerConstant(loc, builder.getI64Type(), 10);
auto c100 = builder.createIntegerConstant(loc, builder.getI64Type(), 100);
llvm::SmallVector<mlir::Value> extents = {c10, c100};
fir::AbstractArrayBox aab(extents, {});
EXPECT_TRUE(aab.lboundsAllOne());
auto shape = builder.genShape(loc, aab);
checkShapeOp(shape, c10, c100);
}
TEST_F(FIRBuilderTest, readCharLen) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
llvm::StringRef strValue("length");
auto strLit = fir::factory::createStringLiteral(builder, loc, strValue);
auto len = fir::factory::readCharLen(builder, loc, strLit);
EXPECT_EQ(strLit.getCharBox()->getLen(), len);
}
TEST_F(FIRBuilderTest, getExtents) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
llvm::StringRef strValue("length");
auto strLit = fir::factory::createStringLiteral(builder, loc, strValue);
auto ext = fir::factory::getExtents(builder, loc, strLit);
EXPECT_EQ(0u, ext.size());
auto c10 = builder.createIntegerConstant(loc, builder.getI64Type(), 10);
auto c100 = builder.createIntegerConstant(loc, builder.getI64Type(), 100);
llvm::SmallVector<mlir::Value> extents = {c10, c100};
fir::SequenceType::Shape shape(2, fir::SequenceType::getUnknownExtent());
auto arrayTy = fir::SequenceType::get(shape, builder.getI64Type());
mlir::Value array = builder.create<fir::UndefOp>(loc, arrayTy);
fir::ArrayBoxValue aab(array, extents, {});
fir::ExtendedValue ex(aab);
auto readExtents = fir::factory::getExtents(builder, loc, ex);
EXPECT_EQ(2u, readExtents.size());
}
TEST_F(FIRBuilderTest, createZeroValue) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
mlir::Type i64Ty = mlir::IntegerType::get(builder.getContext(), 64);
mlir::Value zeroInt = fir::factory::createZeroValue(builder, loc, i64Ty);
EXPECT_TRUE(zeroInt.getType() == i64Ty);
auto cst =
mlir::dyn_cast_or_null<mlir::arith::ConstantOp>(zeroInt.getDefiningOp());
EXPECT_TRUE(cst);
auto intAttr = cst.getValue().dyn_cast<mlir::IntegerAttr>();
EXPECT_TRUE(intAttr && intAttr.getInt() == 0);
mlir::Type f32Ty = mlir::FloatType::getF32(builder.getContext());
mlir::Value zeroFloat = fir::factory::createZeroValue(builder, loc, f32Ty);
EXPECT_TRUE(zeroFloat.getType() == f32Ty);
auto cst2 = mlir::dyn_cast_or_null<mlir::arith::ConstantOp>(
zeroFloat.getDefiningOp());
EXPECT_TRUE(cst2);
auto floatAttr = cst2.getValue().dyn_cast<mlir::FloatAttr>();
EXPECT_TRUE(floatAttr && floatAttr.getValueAsDouble() == 0.);
mlir::Type boolTy = mlir::IntegerType::get(builder.getContext(), 1);
mlir::Value flaseBool = fir::factory::createZeroValue(builder, loc, boolTy);
EXPECT_TRUE(flaseBool.getType() == boolTy);
auto cst3 = mlir::dyn_cast_or_null<mlir::arith::ConstantOp>(
flaseBool.getDefiningOp());
EXPECT_TRUE(cst3);
auto intAttr2 = cst.getValue().dyn_cast<mlir::IntegerAttr>();
EXPECT_TRUE(intAttr2 && intAttr2.getInt() == 0);
}
TEST_F(FIRBuilderTest, getBaseTypeOf) {
auto builder = getBuilder();
auto loc = builder.getUnknownLoc();
auto makeExv = [&](mlir::Type elementType, mlir::Type arrayType)
-> std::tuple<llvm::SmallVector<fir::ExtendedValue, 4>,
llvm::SmallVector<fir::ExtendedValue, 4>> {
auto ptrTyArray = fir::PointerType::get(arrayType);
auto ptrTyScalar = fir::PointerType::get(elementType);
auto ptrBoxTyArray = fir::BoxType::get(ptrTyArray);
auto ptrBoxTyScalar = fir::BoxType::get(ptrTyScalar);
auto boxRefTyArray = fir::ReferenceType::get(ptrBoxTyArray);
auto boxRefTyScalar = fir::ReferenceType::get(ptrBoxTyScalar);
auto boxTyArray = fir::BoxType::get(arrayType);
auto boxTyScalar = fir::BoxType::get(elementType);
auto ptrValArray = builder.create<fir::UndefOp>(loc, ptrTyArray);
auto ptrValScalar = builder.create<fir::UndefOp>(loc, ptrTyScalar);
auto boxRefValArray = builder.create<fir::UndefOp>(loc, boxRefTyArray);
auto boxRefValScalar = builder.create<fir::UndefOp>(loc, boxRefTyScalar);
auto boxValArray = builder.create<fir::UndefOp>(loc, boxTyArray);
auto boxValScalar = builder.create<fir::UndefOp>(loc, boxTyScalar);
llvm::SmallVector<fir::ExtendedValue, 4> scalars;
scalars.emplace_back(fir::UnboxedValue(ptrValScalar));
scalars.emplace_back(fir::BoxValue(boxValScalar));
scalars.emplace_back(
fir::MutableBoxValue(boxRefValScalar, mlir::ValueRange(), {}));
llvm::SmallVector<fir::ExtendedValue, 4> arrays;
auto extent = builder.create<fir::UndefOp>(loc, builder.getIndexType());
llvm::SmallVector<mlir::Value> extents(
arrayType.dyn_cast<fir::SequenceType>().getDimension(),
extent.getResult());
arrays.emplace_back(fir::ArrayBoxValue(ptrValArray, extents));
arrays.emplace_back(fir::BoxValue(boxValArray));
arrays.emplace_back(
fir::MutableBoxValue(boxRefValArray, mlir::ValueRange(), {}));
return {scalars, arrays};
};
auto f32Ty = mlir::FloatType::getF32(builder.getContext());
mlir::Type f32SeqTy = builder.getVarLenSeqTy(f32Ty);
auto [f32Scalars, f32Arrays] = makeExv(f32Ty, f32SeqTy);
for (const auto &scalar : f32Scalars) {
EXPECT_EQ(fir::getBaseTypeOf(scalar), f32Ty);
EXPECT_EQ(fir::getElementTypeOf(scalar), f32Ty);
EXPECT_FALSE(fir::isDerivedWithLengthParameters(scalar));
}
for (const auto &array : f32Arrays) {
EXPECT_EQ(fir::getBaseTypeOf(array), f32SeqTy);
EXPECT_EQ(fir::getElementTypeOf(array), f32Ty);
EXPECT_FALSE(fir::isDerivedWithLengthParameters(array));
}
auto derivedWithLengthTy =
fir::RecordType::get(builder.getContext(), "derived_test");
llvm::SmallVector<std::pair<std::string, mlir::Type>> parameters;
llvm::SmallVector<std::pair<std::string, mlir::Type>> components;
parameters.emplace_back("p1", builder.getI64Type());
components.emplace_back("c1", f32Ty);
derivedWithLengthTy.finalize(parameters, components);
mlir::Type derivedWithLengthSeqTy =
builder.getVarLenSeqTy(derivedWithLengthTy);
auto [derivedWithLengthScalars, derivedWithLengthArrays] =
makeExv(derivedWithLengthTy, derivedWithLengthSeqTy);
for (const auto &scalar : derivedWithLengthScalars) {
EXPECT_EQ(fir::getBaseTypeOf(scalar), derivedWithLengthTy);
EXPECT_EQ(fir::getElementTypeOf(scalar), derivedWithLengthTy);
EXPECT_TRUE(fir::isDerivedWithLengthParameters(scalar));
}
for (const auto &array : derivedWithLengthArrays) {
EXPECT_EQ(fir::getBaseTypeOf(array), derivedWithLengthSeqTy);
EXPECT_EQ(fir::getElementTypeOf(array), derivedWithLengthTy);
EXPECT_TRUE(fir::isDerivedWithLengthParameters(array));
}
}