brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.8 KiB · 95f01e0 Raw
196 lines · cpp
1//===- HLFIRToolsTest.cpp -- HLFIR tools 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-exception6//7//===----------------------------------------------------------------------===//8 9#include "flang/Optimizer/Builder/HLFIRTools.h"10#include "gtest/gtest.h"11#include "flang/Optimizer/Builder/BoxValue.h"12#include "flang/Optimizer/Builder/FIRBuilder.h"13#include "flang/Optimizer/Dialect/Support/KindMapping.h"14#include "flang/Optimizer/Support/InitFIR.h"15 16struct HLFIRToolsTest : public testing::Test {17public:18  void SetUp() override {19    fir::support::loadDialects(context);20 21    llvm::ArrayRef<fir::KindTy> defs;22    fir::KindMapping kindMap(&context, defs);23    mlir::OpBuilder builder(&context);24    auto loc = builder.getUnknownLoc();25 26    // Set up a Module with a dummy function operation inside.27    // Set the insertion point in the function entry block.28    moduleOp = mlir::ModuleOp::create(builder, loc);29    builder.setInsertionPointToStart(moduleOp->getBody());30    mlir::func::FuncOp func = mlir::func::FuncOp::create(31        builder, loc, "func1", builder.getFunctionType({}, {}));32    auto *entryBlock = func.addEntryBlock();33    builder.setInsertionPointToStart(entryBlock);34 35    firBuilder = std::make_unique<fir::FirOpBuilder>(builder, kindMap);36  }37 38  mlir::Value createDeclare(fir::ExtendedValue exv) {39    return hlfir::genDeclare(getLoc(), *firBuilder, exv,40        "x" + std::to_string(varCounter++), fir::FortranVariableFlagsAttr{})41        .getBase();42  }43 44  mlir::Value createConstant(std::int64_t cst) {45    mlir::Type indexType = firBuilder->getIndexType();46    return mlir::arith::ConstantOp::create(*firBuilder, getLoc(), indexType,47        firBuilder->getIntegerAttr(indexType, cst));48  }49 50  mlir::Location getLoc() { return firBuilder->getUnknownLoc(); }51  fir::FirOpBuilder &getBuilder() { return *firBuilder; }52 53  int varCounter = 0;54  mlir::MLIRContext context;55  mlir::OwningOpRef<mlir::ModuleOp> moduleOp;56  std::unique_ptr<fir::FirOpBuilder> firBuilder;57};58 59TEST_F(HLFIRToolsTest, testScalarRoundTrip) {60  auto &builder = getBuilder();61  mlir::Location loc = getLoc();62  mlir::Type f32Type = mlir::Float32Type::get(&context);63  mlir::Type scalarf32Type = builder.getRefType(f32Type);64  mlir::Value scalarf32Addr = fir::UndefOp::create(builder, loc, scalarf32Type);65  fir::ExtendedValue scalarf32{scalarf32Addr};66  hlfir::EntityWithAttributes scalarf32Entity(createDeclare(scalarf32));67  auto [scalarf32Result, cleanup] =68      hlfir::translateToExtendedValue(loc, builder, scalarf32Entity);69  auto *unboxed = scalarf32Result.getUnboxed();70  EXPECT_FALSE(cleanup.has_value());71  ASSERT_NE(unboxed, nullptr);72  EXPECT_TRUE(*unboxed == scalarf32Entity.getFirBase());73  EXPECT_TRUE(scalarf32Entity.isVariable());74  EXPECT_FALSE(scalarf32Entity.isValue());75}76 77TEST_F(HLFIRToolsTest, testArrayRoundTrip) {78  auto &builder = getBuilder();79  mlir::Location loc = getLoc();80  llvm::SmallVector<mlir::Value> extents{81      createConstant(20), createConstant(30)};82  llvm::SmallVector<mlir::Value> lbounds{83      createConstant(-1), createConstant(-2)};84 85  mlir::Type f32Type = mlir::Float32Type::get(&context);86  mlir::Type seqf32Type = builder.getVarLenSeqTy(f32Type, 2);87  mlir::Type arrayf32Type = builder.getRefType(seqf32Type);88  mlir::Value arrayf32Addr = fir::UndefOp::create(builder, loc, arrayf32Type);89  fir::ArrayBoxValue arrayf32{arrayf32Addr, extents, lbounds};90  hlfir::EntityWithAttributes arrayf32Entity(createDeclare(arrayf32));91  auto [arrayf32Result, cleanup] =92      hlfir::translateToExtendedValue(loc, builder, arrayf32Entity);93  auto *res = arrayf32Result.getBoxOf<fir::ArrayBoxValue>();94  EXPECT_FALSE(cleanup.has_value());95  ASSERT_NE(res, nullptr);96  // gtest has a terrible time printing mlir::Value in case of failing97  // EXPECT_EQ(mlir::Value, mlir::Value). So use EXPECT_TRUE instead.98  EXPECT_TRUE(fir::getBase(*res) == arrayf32Entity.getFirBase());99  ASSERT_EQ(res->getExtents().size(), arrayf32.getExtents().size());100  for (unsigned i = 0; i < arrayf32.getExtents().size(); ++i)101    EXPECT_TRUE(res->getExtents()[i] == arrayf32.getExtents()[i]);102  ASSERT_EQ(res->getLBounds().size(), arrayf32.getLBounds().size());103  for (unsigned i = 0; i < arrayf32.getLBounds().size(); ++i)104    EXPECT_TRUE(res->getLBounds()[i] == arrayf32.getLBounds()[i]);105  EXPECT_TRUE(arrayf32Entity.isVariable());106  EXPECT_FALSE(arrayf32Entity.isValue());107}108 109TEST_F(HLFIRToolsTest, testScalarCharRoundTrip) {110  auto &builder = getBuilder();111  mlir::Location loc = getLoc();112  mlir::Value len = createConstant(42);113  mlir::Type charType = fir::CharacterType::getUnknownLen(&context, 1);114  mlir::Type scalarCharType = builder.getRefType(charType);115  mlir::Value scalarCharAddr =116      fir::UndefOp::create(builder, loc, scalarCharType);117  fir::CharBoxValue scalarChar{scalarCharAddr, len};118  hlfir::EntityWithAttributes scalarCharEntity(createDeclare(scalarChar));119  auto [scalarCharResult, cleanup] =120      hlfir::translateToExtendedValue(loc, builder, scalarCharEntity);121  auto *res = scalarCharResult.getBoxOf<fir::CharBoxValue>();122  EXPECT_FALSE(cleanup.has_value());123  ASSERT_NE(res, nullptr);124  EXPECT_TRUE(fir::getBase(*res) == scalarCharEntity.getFirBase());125  EXPECT_TRUE(res->getLen() == scalarChar.getLen());126  EXPECT_TRUE(scalarCharEntity.isVariable());127  EXPECT_FALSE(scalarCharEntity.isValue());128}129 130TEST_F(HLFIRToolsTest, testArrayCharRoundTrip) {131  auto &builder = getBuilder();132  mlir::Location loc = getLoc();133  llvm::SmallVector<mlir::Value> extents{134      createConstant(20), createConstant(30)};135  llvm::SmallVector<mlir::Value> lbounds{136      createConstant(-1), createConstant(-2)};137  mlir::Value len = createConstant(42);138  mlir::Type charType = fir::CharacterType::getUnknownLen(&context, 1);139  mlir::Type seqCharType = builder.getVarLenSeqTy(charType, 2);140  mlir::Type arrayCharType = builder.getRefType(seqCharType);141  mlir::Value arrayCharAddr = fir::UndefOp::create(builder, loc, arrayCharType);142  fir::CharArrayBoxValue arrayChar{arrayCharAddr, len, extents, lbounds};143  hlfir::EntityWithAttributes arrayCharEntity(createDeclare(arrayChar));144  auto [arrayCharResult, cleanup] =145      hlfir::translateToExtendedValue(loc, builder, arrayCharEntity);146  auto *res = arrayCharResult.getBoxOf<fir::CharArrayBoxValue>();147  EXPECT_FALSE(cleanup.has_value());148  ASSERT_NE(res, nullptr);149  // gtest has a terrible time printing mlir::Value in case of failing150  // EXPECT_EQ(mlir::Value, mlir::Value). So use EXPECT_TRUE instead.151  EXPECT_TRUE(fir::getBase(*res) == arrayCharEntity.getFirBase());152  EXPECT_TRUE(res->getLen() == arrayChar.getLen());153  ASSERT_EQ(res->getExtents().size(), arrayChar.getExtents().size());154  for (unsigned i = 0; i < arrayChar.getExtents().size(); ++i)155    EXPECT_TRUE(res->getExtents()[i] == arrayChar.getExtents()[i]);156  ASSERT_EQ(res->getLBounds().size(), arrayChar.getLBounds().size());157  for (unsigned i = 0; i < arrayChar.getLBounds().size(); ++i)158    EXPECT_TRUE(res->getLBounds()[i] == arrayChar.getLBounds()[i]);159  EXPECT_TRUE(arrayCharEntity.isVariable());160  EXPECT_FALSE(arrayCharEntity.isValue());161}162 163TEST_F(HLFIRToolsTest, testArrayCharBoxRoundTrip) {164  auto &builder = getBuilder();165  mlir::Location loc = getLoc();166  llvm::SmallVector<mlir::Value> lbounds{167      createConstant(-1), createConstant(-2)};168  mlir::Value len = createConstant(42);169  mlir::Type charType = fir::CharacterType::getUnknownLen(&context, 1);170  mlir::Type seqCharType = builder.getVarLenSeqTy(charType, 2);171  mlir::Type arrayCharBoxType = fir::BoxType::get(seqCharType);172  mlir::Value arrayCharAddr =173      fir::UndefOp::create(builder, loc, arrayCharBoxType);174  llvm::SmallVector<mlir::Value> explicitTypeParams{len};175  fir::BoxValue arrayChar{arrayCharAddr, lbounds, explicitTypeParams};176  hlfir::EntityWithAttributes arrayCharEntity(createDeclare(arrayChar));177  auto [arrayCharResult, cleanup] =178      hlfir::translateToExtendedValue(loc, builder, arrayCharEntity);179  auto *res = arrayCharResult.getBoxOf<fir::BoxValue>();180  EXPECT_FALSE(cleanup.has_value());181  ASSERT_NE(res, nullptr);182  // gtest has a terrible time printing mlir::Value in case of failing183  // EXPECT_EQ(mlir::Value, mlir::Value). So use EXPECT_TRUE instead.184  EXPECT_TRUE(fir::getBase(*res) == arrayCharEntity.getFirBase());185  ASSERT_EQ(res->getExplicitParameters().size(),186      arrayChar.getExplicitParameters().size());187  for (unsigned i = 0; i < arrayChar.getExplicitParameters().size(); ++i)188    EXPECT_TRUE(res->getExplicitParameters()[i] ==189        arrayChar.getExplicitParameters()[i]);190  ASSERT_EQ(res->getLBounds().size(), arrayChar.getLBounds().size());191  for (unsigned i = 0; i < arrayChar.getLBounds().size(); ++i)192    EXPECT_TRUE(res->getLBounds()[i] == arrayChar.getLBounds()[i]);193  EXPECT_TRUE(arrayCharEntity.isVariable());194  EXPECT_FALSE(arrayCharEntity.isValue());195}196