[flang-commits] [flang] c14ef2d - [flang] Add kernel to lower expressions to HLFIR

Jean Perier via flang-commits flang-commits at lists.llvm.org
Mon Oct 24 06:38:06 PDT 2022


Author: Jean Perier
Date: 2022-10-24T15:36:23+02:00
New Revision: c14ef2d762e4f7de2d892af111d87aec79b8cd6f

URL: https://github.com/llvm/llvm-project/commit/c14ef2d762e4f7de2d892af111d87aec79b8cd6f
DIFF: https://github.com/llvm/llvm-project/commit/c14ef2d762e4f7de2d892af111d87aec79b8cd6f.diff

LOG: [flang] Add kernel to lower expressions to HLFIR

This patch adds the kernel to lower evaluate::Expr to HLFIR to a
hlfir::FortranEntity (a single mlir::Value that can be interpreted as
a Fortran variable or the value of a Fortram expression).

It implements lowering of simple name designators ("x") and starts
adding a translation layer in AbstractConverter::genExprBox and
AbstractConverter::genExprAddr so that the new expression lowering
can be used without any changes for now in the current statement and
construct lowering.

Differential Revision: https://reviews.llvm.org/D136453

Added: 
    flang/include/flang/Lower/ConvertExprToHLFIR.h
    flang/lib/Lower/ConvertExprToHLFIR.cpp

Modified: 
    flang/include/flang/Lower/SymbolMap.h
    flang/include/flang/Optimizer/Builder/FIRBuilder.h
    flang/lib/Lower/Bridge.cpp
    flang/lib/Lower/CMakeLists.txt
    flang/lib/Lower/ConvertVariable.cpp
    flang/lib/Lower/SymbolMap.cpp
    flang/lib/Optimizer/Builder/FIRBuilder.cpp
    flang/test/Lower/HLFIR/expr-addr.f90
    flang/test/Lower/HLFIR/expr-box.f90

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Lower/ConvertExprToHLFIR.h b/flang/include/flang/Lower/ConvertExprToHLFIR.h
new file mode 100644
index 0000000000000..84d2f7d27b8d6
--- /dev/null
+++ b/flang/include/flang/Lower/ConvertExprToHLFIR.h
@@ -0,0 +1,42 @@
+//===-- Lower/ConvertExprToHLFIR.h -- lowering of expressions ----*- C++-*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
+//
+//===----------------------------------------------------------------------===//
+///
+/// Implements the conversion from Fortran::evaluate::Expr trees to HLFIR.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_LOWER_CONVERTEXPRTOHLFIR_H
+#define FORTRAN_LOWER_CONVERTEXPRTOHLFIR_H
+
+#include "flang/Lower/Support/Utils.h"
+#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/HLFIRTools.h"
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+
+namespace mlir {
+class Location;
+} // namespace mlir
+
+namespace Fortran::lower {
+
+class AbstractConverter;
+class StatementContext;
+class SymMap;
+
+hlfir::FortranEntity convertExprToHLFIR(mlir::Location loc,
+                                        Fortran::lower::AbstractConverter &,
+                                        const Fortran::lower::SomeExpr &,
+                                        Fortran::lower::SymMap &,
+                                        Fortran::lower::StatementContext &);
+} // namespace Fortran::lower
+
+#endif // FORTRAN_LOWER_CONVERTEXPRTOHLFIR_H

diff  --git a/flang/include/flang/Lower/SymbolMap.h b/flang/include/flang/Lower/SymbolMap.h
index cd959b6e788de..1ad0427091eb5 100644
--- a/flang/include/flang/Lower/SymbolMap.h
+++ b/flang/include/flang/Lower/SymbolMap.h
@@ -348,6 +348,9 @@ class SymMap {
     symbolMapStack.back().try_emplace(sym, definingOp);
   }
 
+  llvm::Optional<fir::FortranVariableOpInterface>
+  lookupVariableDefinition(semantics::SymbolRef sym);
+
 private:
   /// Add `symbol` to the current map and bind a `box`.
   void makeSym(semantics::SymbolRef symRef, const SymbolBox &box,

diff  --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
index 3567bc44fc095..27c6267b2cd7c 100644
--- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h
+++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
@@ -561,6 +561,10 @@ mlir::Value genMaxWithZero(fir::FirOpBuilder &builder, mlir::Location loc,
 mlir::Value genCPtrOrCFunptrAddr(fir::FirOpBuilder &builder, mlir::Location loc,
                                  mlir::Value cPtr, mlir::Type ty);
 
+/// Create a fir.box from a fir::ExtendedValue and wrap it in a fir::BoxValue
+/// to keep all the lower bound and explicit parameter information.
+fir::BoxValue createBoxValue(fir::FirOpBuilder &builder, mlir::Location loc,
+                             const fir::ExtendedValue &exv);
 } // namespace fir::factory
 
 #endif // FORTRAN_OPTIMIZER_BUILDER_FIRBUILDER_H

diff  --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index c98e335d85bd5..db8c2b7afbb8d 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -15,6 +15,7 @@
 #include "flang/Lower/CallInterface.h"
 #include "flang/Lower/Coarray.h"
 #include "flang/Lower/ConvertExpr.h"
+#include "flang/Lower/ConvertExprToHLFIR.h"
 #include "flang/Lower/ConvertType.h"
 #include "flang/Lower/ConvertVariable.h"
 #include "flang/Lower/HostAssociations.h"
@@ -416,16 +417,35 @@ class FirConverter : public Fortran::lower::AbstractConverter {
     return iter->second;
   }
 
+  fir::ExtendedValue
+  translateToExtendedValue(mlir::Location loc, hlfir::FortranEntity entity,
+                           Fortran::lower::StatementContext &context) {
+    auto [exv, exvCleanup] =
+        hlfir::translateToExtendedValue(loc, getFirOpBuilder(), entity);
+    if (exvCleanup)
+      context.attachCleanup(*exvCleanup);
+    return exv;
+  }
+
   fir::ExtendedValue
   genExprAddr(const Fortran::lower::SomeExpr &expr,
               Fortran::lower::StatementContext &context,
               mlir::Location *locPtr = nullptr) override final {
     mlir::Location loc = locPtr ? *locPtr : toLocation();
-    if (bridge.getLoweringOptions().getLowerToHighLevelFIR())
-      TODO(loc, "lower expr to HLFIR address");
+    if (bridge.getLoweringOptions().getLowerToHighLevelFIR()) {
+      hlfir::FortranEntity loweredExpr = Fortran::lower::convertExprToHLFIR(
+          loc, *this, expr, localSymbols, context);
+      if (fir::FortranVariableOpInterface variable =
+              loweredExpr.getIfVariable())
+        if (!variable.isBox())
+          return translateToExtendedValue(loc, loweredExpr, context);
+      TODO(loc, "lower expr that is not a scalar or explicit shape array "
+                "variable to HLFIR address");
+    }
     return Fortran::lower::createSomeExtendedAddress(loc, *this, expr,
                                                      localSymbols, context);
   }
+
   fir::ExtendedValue
   genExprValue(const Fortran::lower::SomeExpr &expr,
                Fortran::lower::StatementContext &context,
@@ -440,8 +460,18 @@ class FirConverter : public Fortran::lower::AbstractConverter {
   fir::ExtendedValue
   genExprBox(mlir::Location loc, const Fortran::lower::SomeExpr &expr,
              Fortran::lower::StatementContext &stmtCtx) override final {
-    if (bridge.getLoweringOptions().getLowerToHighLevelFIR())
-      TODO(loc, "lower expr to HLFIR box");
+    if (bridge.getLoweringOptions().getLowerToHighLevelFIR()) {
+      hlfir::FortranEntity loweredExpr = Fortran::lower::convertExprToHLFIR(
+          loc, *this, expr, localSymbols, stmtCtx);
+      if (fir::FortranVariableOpInterface variable =
+              loweredExpr.getIfVariable())
+        if (variable.isBoxValue() || !variable.isBoxAddress()) {
+          auto exv = translateToExtendedValue(loc, loweredExpr, stmtCtx);
+          return fir::factory::createBoxValue(getFirOpBuilder(), loc, exv);
+        }
+      TODO(loc,
+           "lower expression value or pointer and allocatable to HLFIR box");
+    }
     return Fortran::lower::createBoxValue(loc, *this, expr, localSymbols,
                                           stmtCtx);
   }

diff  --git a/flang/lib/Lower/CMakeLists.txt b/flang/lib/Lower/CMakeLists.txt
index 2874084e7e559..bf0df69830965 100644
--- a/flang/lib/Lower/CMakeLists.txt
+++ b/flang/lib/Lower/CMakeLists.txt
@@ -6,6 +6,7 @@ add_flang_library(FortranLower
   CallInterface.cpp
   Coarray.cpp
   ConvertExpr.cpp
+  ConvertExprToHLFIR.cpp
   ConvertType.cpp
   ConvertVariable.cpp
   ComponentPath.cpp
@@ -28,6 +29,7 @@ add_flang_library(FortranLower
   FIRBuilder
   FIRSupport
   FIRTransforms
+  HLFIRDialect
   ${dialect_libs}
 
   LINK_LIBS
@@ -35,6 +37,7 @@ add_flang_library(FortranLower
   FIRBuilder
   FIRSupport
   FIRTransforms
+  HLFIRDialect
   ${dialect_libs}
   FortranCommon
   FortranParser

diff  --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
new file mode 100644
index 0000000000000..d2f6ba4added2
--- /dev/null
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -0,0 +1,195 @@
+//===-- ConvertExprToHLFIR.cpp --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Lower/ConvertExprToHLFIR.h"
+#include "flang/Lower/AbstractConverter.h"
+#include "flang/Lower/StatementContext.h"
+#include "flang/Lower/SymbolMap.h"
+#include "flang/Optimizer/Builder/Todo.h"
+
+namespace {
+
+/// Lower Designators to HLFIR.
+class HlfirDesignatorBuilder {
+public:
+  HlfirDesignatorBuilder(mlir::Location loc,
+                         Fortran::lower::AbstractConverter &converter,
+                         Fortran::lower::SymMap &symMap,
+                         Fortran::lower::StatementContext &stmtCtx)
+      : converter{converter}, symMap{symMap}, stmtCtx{stmtCtx}, loc{loc} {}
+
+  // Character designators variant contains substrings
+  using CharacterDesignators =
+      decltype(Fortran::evaluate::Designator<Fortran::evaluate::Type<
+                   Fortran::evaluate::TypeCategory::Character, 1>>::u);
+  hlfir::FortranEntity gen(const CharacterDesignators &designatorVariant) {
+    return std::visit([&](const auto &x) { return gen(x); }, designatorVariant);
+  }
+  // Character designators variant contains complex parts
+  using RealDesignators =
+      decltype(Fortran::evaluate::Designator<Fortran::evaluate::Type<
+                   Fortran::evaluate::TypeCategory::Real, 4>>::u);
+  hlfir::FortranEntity gen(const RealDesignators &designatorVariant) {
+    return std::visit([&](const auto &x) { return gen(x); }, designatorVariant);
+  }
+  // All other designators are similar
+  using OtherDesignators =
+      decltype(Fortran::evaluate::Designator<Fortran::evaluate::Type<
+                   Fortran::evaluate::TypeCategory::Integer, 4>>::u);
+  hlfir::FortranEntity gen(const OtherDesignators &designatorVariant) {
+    return std::visit([&](const auto &x) { return gen(x); }, designatorVariant);
+  }
+
+private:
+  hlfir::FortranEntity gen(const Fortran::evaluate::SymbolRef &symbolRef) {
+    if (llvm::Optional<fir::FortranVariableOpInterface> varDef =
+            getSymMap().lookupVariableDefinition(symbolRef))
+      return *varDef;
+    TODO(getLoc(), "lowering symbol to HLFIR");
+  }
+  hlfir::FortranEntity gen(const Fortran::evaluate::Component &component) {
+    TODO(getLoc(), "lowering component to HLFIR");
+  }
+  hlfir::FortranEntity gen(const Fortran::evaluate::ArrayRef &arrayRef) {
+    TODO(getLoc(), "lowering ArrayRef to HLFIR");
+  }
+  hlfir::FortranEntity gen(const Fortran::evaluate::CoarrayRef &coarrayRef) {
+    TODO(getLoc(), "lowering CoarrayRef to HLFIR");
+  }
+  hlfir::FortranEntity gen(const Fortran::evaluate::ComplexPart &complexPart) {
+    TODO(getLoc(), "lowering complex part to HLFIR");
+  }
+  hlfir::FortranEntity gen(const Fortran::evaluate::Substring &substring) {
+    TODO(getLoc(), "lowering substrings to HLFIR");
+  }
+
+  mlir::Location getLoc() const { return loc; }
+  Fortran::lower::AbstractConverter &getConverter() { return converter; }
+  fir::FirOpBuilder &getBuilder() { return converter.getFirOpBuilder(); }
+  Fortran::lower::SymMap &getSymMap() { return symMap; }
+  Fortran::lower::StatementContext &getStmtCtx() { return stmtCtx; }
+
+  Fortran::lower::AbstractConverter &converter;
+  Fortran::lower::SymMap &symMap;
+  Fortran::lower::StatementContext &stmtCtx;
+  mlir::Location loc;
+};
+
+/// Lower Expr to HLFIR.
+class HlfirBuilder {
+public:
+  HlfirBuilder(mlir::Location loc, Fortran::lower::AbstractConverter &converter,
+               Fortran::lower::SymMap &symMap,
+               Fortran::lower::StatementContext &stmtCtx)
+      : converter{converter}, symMap{symMap}, stmtCtx{stmtCtx}, loc{loc} {}
+
+  template <typename T>
+  hlfir::FortranEntity gen(const Fortran::evaluate::Expr<T> &expr) {
+    return std::visit([&](const auto &x) { return gen(x); }, expr.u);
+  }
+
+private:
+  hlfir::FortranEntity gen(const Fortran::evaluate::BOZLiteralConstant &expr) {
+    fir::emitFatalError(loc, "BOZ literal must be replaced by semantics");
+  }
+  hlfir::FortranEntity gen(const Fortran::evaluate::NullPointer &expr) {
+    TODO(getLoc(), "lowering NullPointer to HLFIR");
+  }
+  hlfir::FortranEntity gen(const Fortran::evaluate::ProcedureDesignator &expr) {
+    TODO(getLoc(), "lowering ProcDes to HLFIR");
+  }
+  hlfir::FortranEntity gen(const Fortran::evaluate::ProcedureRef &expr) {
+    TODO(getLoc(), "lowering ProcRef to HLFIR");
+  }
+
+  template <typename T>
+  hlfir::FortranEntity gen(const Fortran::evaluate::Designator<T> &designator) {
+    return HlfirDesignatorBuilder(getLoc(), getConverter(), getSymMap(),
+                                  getStmtCtx())
+        .gen(designator.u);
+  }
+
+  template <typename T>
+  hlfir::FortranEntity gen(const Fortran::evaluate::FunctionRef<T> &expr) {
+    TODO(getLoc(), "lowering funcRef to HLFIR");
+  }
+
+  template <typename T>
+  hlfir::FortranEntity gen(const Fortran::evaluate::Constant<T> &expr) {
+    TODO(getLoc(), "lowering constant to HLFIR");
+  }
+
+  template <typename T>
+  hlfir::FortranEntity gen(const Fortran::evaluate::ArrayConstructor<T> &expr) {
+    TODO(getLoc(), "lowering ArrayCtor to HLFIR");
+  }
+
+  template <Fortran::common::TypeCategory TC1, int KIND,
+            Fortran::common::TypeCategory TC2>
+  hlfir::FortranEntity
+  gen(const Fortran::evaluate::Convert<Fortran::evaluate::Type<TC1, KIND>, TC2>
+          &convert) {
+    TODO(getLoc(), "lowering convert to HLFIR");
+  }
+
+  template <typename D, typename R, typename O>
+  hlfir::FortranEntity gen(const Fortran::evaluate::Operation<D, R, O> &op) {
+    TODO(getLoc(), "lowering unary op to HLFIR");
+  }
+
+  template <typename D, typename R, typename LO, typename RO>
+  hlfir::FortranEntity
+  gen(const Fortran::evaluate::Operation<D, R, LO, RO> &op) {
+    TODO(getLoc(), "lowering binary op to HLFIR");
+  }
+
+  hlfir::FortranEntity
+  gen(const Fortran::evaluate::Relational<Fortran::evaluate::SomeType> &op) {
+    return std::visit([&](const auto &x) { return gen(x); }, op.u);
+  }
+
+  hlfir::FortranEntity gen(const Fortran::evaluate::TypeParamInquiry &) {
+    TODO(getLoc(), "lowering type parameter inquiry to HLFIR");
+  }
+
+  hlfir::FortranEntity gen(const Fortran::evaluate::DescriptorInquiry &desc) {
+    TODO(getLoc(), "lowering descriptor inquiry to HLFIR");
+  }
+
+  hlfir::FortranEntity gen(const Fortran::evaluate::ImpliedDoIndex &var) {
+    TODO(getLoc(), "lowering implied do index to HLFIR");
+  }
+
+  hlfir::FortranEntity gen(const Fortran::evaluate::StructureConstructor &var) {
+    TODO(getLoc(), "lowering structure constructor to HLFIR");
+  }
+
+  mlir::Location getLoc() const { return loc; }
+  Fortran::lower::AbstractConverter &getConverter() { return converter; }
+  fir::FirOpBuilder &getBuilder() { return converter.getFirOpBuilder(); }
+  Fortran::lower::SymMap &getSymMap() { return symMap; }
+  Fortran::lower::StatementContext &getStmtCtx() { return stmtCtx; }
+
+  Fortran::lower::AbstractConverter &converter;
+  Fortran::lower::SymMap &symMap;
+  Fortran::lower::StatementContext &stmtCtx;
+  mlir::Location loc;
+};
+
+} // namespace
+
+hlfir::FortranEntity Fortran::lower::convertExprToHLFIR(
+    mlir::Location loc, Fortran::lower::AbstractConverter &converter,
+    const Fortran::lower::SomeExpr &expr, Fortran::lower::SymMap &symMap,
+    Fortran::lower::StatementContext &stmtCtx) {
+  return HlfirBuilder(loc, converter, symMap, stmtCtx).gen(expr);
+}

diff  --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index d2b1e6b5c7e77..fd466c320d216 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -1359,7 +1359,7 @@ static void genDeclareSymbol(Fortran::lower::AbstractConverter &converter,
     auto newBase = builder.create<fir::DeclareOp>(
         loc, base.getType(), base, shapeOrShift, lenParams, name, attributes);
     base = newBase;
-    symMap.addVariableDefinition(sym, newBase);
+    symMap.addVariableDefinition(sym, newBase, force);
     return;
   }
 

diff  --git a/flang/lib/Lower/SymbolMap.cpp b/flang/lib/Lower/SymbolMap.cpp
index 2862341ea61fc..73986c220fc29 100644
--- a/flang/lib/Lower/SymbolMap.cpp
+++ b/flang/lib/Lower/SymbolMap.cpp
@@ -90,6 +90,22 @@ Fortran::lower::SymMap::lookupImpliedDo(Fortran::lower::SymMap::AcDoVar var) {
   return {};
 }
 
+llvm::Optional<fir::FortranVariableOpInterface>
+Fortran::lower::SymMap::lookupVariableDefinition(semantics::SymbolRef sym) {
+  for (auto jmap = symbolMapStack.rbegin(), jend = symbolMapStack.rend();
+       jmap != jend; ++jmap) {
+    auto iter = jmap->find(&*sym);
+    if (iter != jmap->end()) {
+      if (const auto *varDef =
+              std::get_if<fir::FortranVariableOpInterface>(&iter->second))
+        return *varDef;
+      else
+        return llvm::None;
+    }
+  }
+  return llvm::None;
+}
+
 llvm::raw_ostream &
 Fortran::lower::operator<<(llvm::raw_ostream &os,
                            const Fortran::lower::SymbolBox &symBox) {

diff  --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
index 2d65d169621d8..d153ff6b283ab 100644
--- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp
+++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
@@ -1323,3 +1323,30 @@ mlir::Value fir::factory::genCPtrOrCFunptrAddr(fir::FirOpBuilder &builder,
   return builder.create<fir::CoordinateOp>(loc, builder.getRefType(fieldTy),
                                            cPtr, field);
 }
+
+fir::BoxValue fir::factory::createBoxValue(fir::FirOpBuilder &builder,
+                                           mlir::Location loc,
+                                           const fir::ExtendedValue &exv) {
+  if (auto *boxValue = exv.getBoxOf<fir::BoxValue>())
+    return *boxValue;
+  mlir::Value box = builder.createBox(loc, exv);
+  llvm::SmallVector<mlir::Value> lbounds;
+  llvm::SmallVector<mlir::Value> explicitTypeParams;
+  exv.match(
+      [&](const fir::ArrayBoxValue &box) {
+        lbounds.append(box.getLBounds().begin(), box.getLBounds().end());
+      },
+      [&](const fir::CharArrayBoxValue &box) {
+        lbounds.append(box.getLBounds().begin(), box.getLBounds().end());
+        explicitTypeParams.emplace_back(box.getLen());
+      },
+      [&](const fir::CharBoxValue &box) {
+        explicitTypeParams.emplace_back(box.getLen());
+      },
+      [&](const fir::MutableBoxValue &x) {
+        explicitTypeParams.append(x.nonDeferredLenParams().begin(),
+                                  x.nonDeferredLenParams().end());
+      },
+      [](const auto &) {});
+  return fir::BoxValue(box, lbounds, explicitTypeParams);
+}

diff  --git a/flang/test/Lower/HLFIR/expr-addr.f90 b/flang/test/Lower/HLFIR/expr-addr.f90
index 1af59e6cb0548..5900d4a971273 100644
--- a/flang/test/Lower/HLFIR/expr-addr.f90
+++ b/flang/test/Lower/HLFIR/expr-addr.f90
@@ -1,8 +1,12 @@
 ! Test lowering of of expressions as address
-! RUN: %not_todo_cmd bbc -emit-fir -hlfir -o - %s 2>&1 | FileCheck %s
+! RUN: bbc -emit-fir -hlfir -o - %s 2>&1 | FileCheck %s
 
+! CHECK-LABEL: func.func @_QPfoo(
+! CHECK-SAME: %[[arg0:.*]]: !fir.ref<i32>
 subroutine foo(x)
   integer :: x
-  ! CHECK: not yet implemented: lower expr to HLFIR address
   read (*,*) x
+  ! CHECK: %[[x:.]] = fir.declare %[[arg0]] {uniq_name = "_QFfooEx"} : (!fir.ref<i32>) -> !fir.ref<i32>
+  ! CHECK: %[[x_cast:.*]] = fir.convert %[[x]] : (!fir.ref<i32>) -> !fir.ref<i64>
+  ! CHECK: fir.call @_FortranAioInputInteger(%{{.*}}, %[[x_cast]], %{{.*}}) : (!fir.ref<i8>, !fir.ref<i64>, i32) -> i1
 end subroutine

diff  --git a/flang/test/Lower/HLFIR/expr-box.f90 b/flang/test/Lower/HLFIR/expr-box.f90
index c15519974ea20..b55456a81c1fd 100644
--- a/flang/test/Lower/HLFIR/expr-box.f90
+++ b/flang/test/Lower/HLFIR/expr-box.f90
@@ -1,8 +1,14 @@
 ! Test lowering of of expressions as fir.box
-! RUN: %not_todo_cmd bbc -emit-fir -hlfir -o - %s 2>&1 | FileCheck %s
+! RUN: bbc -hlfir -o - %s 2>&1 | FileCheck %s
 
+! CHECK-LABEL: func.func @_QPfoo(
+! CHECK-SAME:  %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>
 subroutine foo(x)
-  integer :: x(:)
-  ! CHECK: not yet implemented: generate fir.declare for box
+  integer :: x(21:30)
   print *, x 
+! CHECK-DAG:  %[[VAL_3:.*]] = arith.constant 21 : index
+! CHECK-DAG:  %[[VAL_4:.*]] = arith.constant 10 : index
+! CHECK:  %[[VAL_5:.*]] = fir.shape_shift %[[VAL_4]], %[[VAL_3]] : (index, index) -> !fir.shapeshift<1>
+! CHECK:  %[[VAL_6:.*]] = fir.declare %[[VAL_0]](%[[VAL_5]]) {uniq_name = "_QFfooEx"} : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>) -> !fir.ref<!fir.array<10xi32>>
+! CHECK:  fir.embox %[[VAL_6]](%[[VAL_5]]) : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<10xi32>>
 end subroutine


        


More information about the flang-commits mailing list