[flang-commits] [flang] ff2912a - [flang][hlfir] place scalar in memory in convertToBox/convertToAddress

Jean Perier via flang-commits flang-commits at lists.llvm.org
Tue Feb 7 00:27:05 PST 2023


Author: Jean Perier
Date: 2023-02-07T09:26:01+01:00
New Revision: ff2912a049195e0557770a5ec33bcf1c718a5afc

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

LOG: [flang][hlfir] place scalar in memory in convertToBox/convertToAddress

Implement the TODO. Be careful to use and propagate the expression
type to create the temporary since the mlir value may have been computed
with a different value type (e.g., i1 for logical) that should not be
used for in memory values that must have Fortran types.

Co-authored-by: Tom Eccles <tom.eccles at arm.com>

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

Added: 
    

Modified: 
    flang/include/flang/Lower/ConvertExprToHLFIR.h
    flang/lib/Lower/ConvertCall.cpp
    flang/lib/Lower/ConvertExprToHLFIR.cpp
    flang/test/Lower/HLFIR/expr-box.f90

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Lower/ConvertExprToHLFIR.h b/flang/include/flang/Lower/ConvertExprToHLFIR.h
index eea2b644801e4..84968917c5857 100644
--- a/flang/include/flang/Lower/ConvertExprToHLFIR.h
+++ b/flang/include/flang/Lower/ConvertExprToHLFIR.h
@@ -57,7 +57,8 @@ fir::BoxValue convertExprToBox(mlir::Location loc,
 fir::BoxValue convertToBox(mlir::Location loc,
                            Fortran::lower::AbstractConverter &,
                            hlfir::Entity entity,
-                           Fortran::lower::StatementContext &);
+                           Fortran::lower::StatementContext &,
+                           mlir::Type fortranType);
 
 /// Lower an evaluate::Expr to fir::ExtendedValue address.
 /// The address may be a raw fir.ref<T>, or a fir.box<T>/fir.class<T>, (pointer
@@ -90,7 +91,8 @@ fir::ExtendedValue convertExprToAddress(mlir::Location loc,
 fir::ExtendedValue convertToAddress(mlir::Location loc,
                                     Fortran::lower::AbstractConverter &,
                                     hlfir::Entity entity,
-                                    Fortran::lower::StatementContext &);
+                                    Fortran::lower::StatementContext &,
+                                    mlir::Type fortranType);
 
 /// Lower an evaluate::Expr to a fir::ExtendedValue value.
 fir::ExtendedValue convertExprToValue(mlir::Location loc,

diff  --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp
index 751e57c55a278..3e8ea0534eb5d 100644
--- a/flang/lib/Lower/ConvertCall.cpp
+++ b/flang/lib/Lower/ConvertCall.cpp
@@ -1098,6 +1098,16 @@ genIntrinsicRefCore(PreparedActualArguments &loweredActuals,
           Fortran::lower::convertToValue(loc, converter, actual, stmtCtx));
       continue;
     }
+    // Helper to get the type of the Fortran expression in case it is a
+    // computed value that must be placed in memory (logicals are computed as
+    // i1, but must be placed in memory as fir.logical).
+    auto getActualFortranElementType = [&]() {
+      const Fortran::lower::SomeExpr *expr =
+          callContext.procRef.UnwrapArgExpr(arg.index());
+      assert(expr && "must be an expr");
+      mlir::Type type = converter.genType(*expr);
+      return hlfir::getFortranElementType(type);
+    };
     // Ad-hoc argument lowering handling.
     fir::ArgLoweringRule argRules =
         fir::lowerIntrinsicArgumentAs(*argLowering, arg.index());
@@ -1107,12 +1117,12 @@ genIntrinsicRefCore(PreparedActualArguments &loweredActuals,
           Fortran::lower::convertToValue(loc, converter, actual, stmtCtx));
       continue;
     case fir::LowerIntrinsicArgAs::Addr:
-      operands.emplace_back(
-          Fortran::lower::convertToAddress(loc, converter, actual, stmtCtx));
+      operands.emplace_back(Fortran::lower::convertToAddress(
+          loc, converter, actual, stmtCtx, getActualFortranElementType()));
       continue;
     case fir::LowerIntrinsicArgAs::Box:
-      operands.emplace_back(
-          Fortran::lower::convertToBox(loc, converter, actual, stmtCtx));
+      operands.emplace_back(Fortran::lower::convertToBox(
+          loc, converter, actual, stmtCtx, getActualFortranElementType()));
       continue;
     case fir::LowerIntrinsicArgAs::Inquired:
       // Place hlfir.expr in memory, and unbox fir.boxchar. Other entities

diff  --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
index 952456738510d..f13822ec55904 100644
--- a/flang/lib/Lower/ConvertExprToHLFIR.cpp
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -1254,13 +1254,24 @@ hlfir::EntityWithAttributes Fortran::lower::convertExprToHLFIR(
   return HlfirBuilder(loc, converter, symMap, stmtCtx).gen(expr);
 }
 
+static fir::ExtendedValue placeTrivialInMemory(mlir::Location loc,
+                                               fir::FirOpBuilder &builder,
+                                               mlir::Value val,
+                                               mlir::Type fortranType) {
+  auto temp = builder.createTemporary(loc, fortranType);
+  builder.createStoreWithConvert(loc, val, temp);
+  return temp;
+}
+
 fir::BoxValue Fortran::lower::convertToBox(
     mlir::Location loc, Fortran::lower::AbstractConverter &converter,
-    hlfir::Entity entity, Fortran::lower::StatementContext &stmtCtx) {
+    hlfir::Entity entity, Fortran::lower::StatementContext &stmtCtx,
+    mlir::Type fortranType) {
   auto exv = Fortran::lower::translateToExtendedValue(
       loc, converter.getFirOpBuilder(), entity, stmtCtx);
   if (fir::isa_trivial(fir::getBase(exv).getType()))
-    TODO(loc, "place trivial in memory");
+    exv = placeTrivialInMemory(loc, converter.getFirOpBuilder(),
+                               fir::getBase(exv), fortranType);
   return fir::factory::createBoxValue(converter.getFirOpBuilder(), loc, exv);
 }
 fir::BoxValue Fortran::lower::convertExprToBox(
@@ -1269,27 +1280,31 @@ fir::BoxValue Fortran::lower::convertExprToBox(
     Fortran::lower::StatementContext &stmtCtx) {
   hlfir::EntityWithAttributes loweredExpr =
       HlfirBuilder(loc, converter, symMap, stmtCtx).gen(expr);
-  return convertToBox(loc, converter, loweredExpr, stmtCtx);
+  return convertToBox(loc, converter, loweredExpr, stmtCtx,
+                      converter.genType(expr));
 }
 
 fir::ExtendedValue Fortran::lower::convertToAddress(
     mlir::Location loc, Fortran::lower::AbstractConverter &converter,
-    hlfir::Entity entity, Fortran::lower::StatementContext &stmtCtx) {
+    hlfir::Entity entity, Fortran::lower::StatementContext &stmtCtx,
+    mlir::Type fortranType) {
   fir::FirOpBuilder &builder = converter.getFirOpBuilder();
   entity = hlfir::derefPointersAndAllocatables(loc, builder, entity);
   fir::ExtendedValue exv =
       Fortran::lower::translateToExtendedValue(loc, builder, entity, stmtCtx);
   if (fir::isa_trivial(fir::getBase(exv).getType()))
-    TODO(loc, "place trivial in memory");
+    return placeTrivialInMemory(loc, builder, fir::getBase(exv), fortranType);
   return exv;
 }
+
 fir::ExtendedValue Fortran::lower::convertExprToAddress(
     mlir::Location loc, Fortran::lower::AbstractConverter &converter,
     const Fortran::lower::SomeExpr &expr, Fortran::lower::SymMap &symMap,
     Fortran::lower::StatementContext &stmtCtx) {
   hlfir::EntityWithAttributes loweredExpr =
       HlfirBuilder(loc, converter, symMap, stmtCtx).gen(expr);
-  return convertToAddress(loc, converter, loweredExpr, stmtCtx);
+  return convertToAddress(loc, converter, loweredExpr, stmtCtx,
+                          converter.genType(expr));
 }
 
 fir::ExtendedValue Fortran::lower::convertToValue(

diff  --git a/flang/test/Lower/HLFIR/expr-box.f90 b/flang/test/Lower/HLFIR/expr-box.f90
index b87190731ea14..330e857aa9b76 100644
--- a/flang/test/Lower/HLFIR/expr-box.f90
+++ b/flang/test/Lower/HLFIR/expr-box.f90
@@ -5,10 +5,36 @@
 ! CHECK-SAME:  %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>
 subroutine foo(x)
   integer :: x(21:30)
-  print *, x 
+  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_3]], %[[VAL_4]] : (index, index) -> !fir.shapeshift<1>
 ! CHECK:  %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_5]]) {uniq_name = "_QFfooEx"} : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>) -> (!fir.box<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
 ! CHECK:  fir.embox %[[VAL_6]]#1(%[[VAL_5]]) : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<10xi32>>
 end subroutine
+
+subroutine test_place_in_memory_and_embox()
+ logical(8) :: a, b
+ write(06), a.and.b
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_place_in_memory_and_embox(
+! CHECK:  %[[TEMP:.*]] = fir.alloca !fir.logical<8>
+! CHECK:  %[[AND:.*]] = arith.andi {{.*}}
+! CHECK:  %[[CAST:.*]] = fir.convert %[[AND]] : (i1) -> !fir.logical<8>
+! CHECK:  fir.store %[[CAST]] to %[[TEMP]] : !fir.ref<!fir.logical<8>>
+! CHECK:  %[[BOX:.*]] = fir.embox %[[TEMP]] : (!fir.ref<!fir.logical<8>>) -> !fir.box<!fir.logical<8>>
+! CHECK:  %[[BOX_CAST:.*]] = fir.convert %[[BOX]] : (!fir.box<!fir.logical<8>>) -> !fir.box<none>
+! CHECK:  fir.call @_FortranAioOutputDescriptor(%{{.*}}, %[[BOX_CAST]])
+
+! check we can box a trivial value
+subroutine sumMask(s, a)
+  integer :: s
+  integer :: a(:)
+  s = sum(a, mask=.true.)
+endsubroutine
+! CHECK-LABEL: func.func @_QPsummask(
+! CHECK:      %[[TRUE:.*]] = arith.constant true
+! CHECK:      %[[ALLOC:.*]] = fir.alloca !fir.logical<4>
+! CHECK:      %[[TRUE_L4:.*]] = fir.convert %[[TRUE]] : (i1) -> !fir.logical<4>
+! CHECK-NEXT: fir.store %[[TRUE_L4]] to %[[ALLOC]]
+! CHECK-NEXT: %[[BOX:.*]] = fir.embox %[[ALLOC]] : (!fir.ref<!fir.logical<4>>) -> !fir.box<!fir.logical<4>>


        


More information about the flang-commits mailing list