[flang-commits] [flang] a02f750 - [flang] Create a box instead of a temp to write to a char array

Valentin Clement via flang-commits flang-commits at lists.llvm.org
Mon Sep 5 04:29:30 PDT 2022


Author: Valentin Clement
Date: 2022-09-05T13:29:21+02:00
New Revision: a02f7505751eb2b13ba2d8d62ca897d1aaf9d0f0

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

LOG: [flang] Create a box instead of a temp to write to a char array

Reviewed By: jeanPerier

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

Added: 
    flang/test/Lower/io-char-array.f90

Modified: 
    flang/lib/Lower/IO.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp
index 00fa17e4508dc..14642146df015 100644
--- a/flang/lib/Lower/IO.cpp
+++ b/flang/lib/Lower/IO.cpp
@@ -1315,11 +1315,11 @@ constexpr bool isDataTransferInternal<Fortran::parser::PrintStmt>(
 /// (normally 1), then a descriptor is required by the runtime IO API. This
 /// condition holds even in F77 sources.
 static llvm::Optional<fir::ExtendedValue> getVariableBufferRequiredDescriptor(
-    Fortran::lower::AbstractConverter &converter,
+    Fortran::lower::AbstractConverter &converter, mlir::Location loc,
     const Fortran::parser::Variable &var,
     Fortran::lower::StatementContext &stmtCtx) {
   fir::ExtendedValue varBox =
-      converter.genExprAddr(var.typedExpr->v.value(), stmtCtx);
+      converter.genExprBox(loc, var.typedExpr->v.value(), stmtCtx);
   fir::KindTy defCharKind = converter.getKindMap().defaultCharacterKind();
   mlir::Value varAddr = fir::getBase(varBox);
   if (fir::factory::CharacterExprHelper::getCharacterOrSequenceKind(
@@ -1333,21 +1333,21 @@ static llvm::Optional<fir::ExtendedValue> getVariableBufferRequiredDescriptor(
 template <typename A>
 static llvm::Optional<fir::ExtendedValue>
 maybeGetInternalIODescriptor(Fortran::lower::AbstractConverter &converter,
-                             const A &stmt,
+                             mlir::Location loc, const A &stmt,
                              Fortran::lower::StatementContext &stmtCtx) {
   if (stmt.iounit.has_value())
     if (auto *var = std::get_if<Fortran::parser::Variable>(&stmt.iounit->u))
-      return getVariableBufferRequiredDescriptor(converter, *var, stmtCtx);
+      return getVariableBufferRequiredDescriptor(converter, loc, *var, stmtCtx);
   if (auto *unit = getIOControl<Fortran::parser::IoUnit>(stmt))
     if (auto *var = std::get_if<Fortran::parser::Variable>(&unit->u))
-      return getVariableBufferRequiredDescriptor(converter, *var, stmtCtx);
+      return getVariableBufferRequiredDescriptor(converter, loc, *var, stmtCtx);
   return llvm::None;
 }
 template <>
 inline llvm::Optional<fir::ExtendedValue>
 maybeGetInternalIODescriptor<Fortran::parser::PrintStmt>(
-    Fortran::lower::AbstractConverter &, const Fortran::parser::PrintStmt &,
-    Fortran::lower::StatementContext &) {
+    Fortran::lower::AbstractConverter &, mlir::Location loc,
+    const Fortran::parser::PrintStmt &, Fortran::lower::StatementContext &) {
   return llvm::None;
 }
 
@@ -1933,7 +1933,7 @@ genDataTransferStmt(Fortran::lower::AbstractConverter &converter,
   const bool isList = isFormatted ? isDataTransferList(stmt) : false;
   const bool isInternal = isDataTransferInternal(stmt);
   llvm::Optional<fir::ExtendedValue> descRef =
-      isInternal ? maybeGetInternalIODescriptor(converter, stmt, stmtCtx)
+      isInternal ? maybeGetInternalIODescriptor(converter, loc, stmt, stmtCtx)
                  : llvm::None;
   const bool isInternalWithDesc = descRef.has_value();
   const bool isAsync = isDataTransferAsynchronous(loc, stmt);

diff  --git a/flang/test/Lower/io-char-array.f90 b/flang/test/Lower/io-char-array.f90
new file mode 100644
index 0000000000000..e2ce6d7edeb65
--- /dev/null
+++ b/flang/test/Lower/io-char-array.f90
@@ -0,0 +1,27 @@
+! Check that a box is created instead of a temp to write to a char array.
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+subroutine io_char_array
+  character(12) :: r(2) = 'badbadbadbad'
+  write(r(1:2),8)
+  print *, r
+1 format((1X,A))
+8 format("new"/"data")
+end subroutine
+
+! CHECK-LABEL: func.func @_QPio_char_array()
+! CHECK: %[[R:.*]] = fir.address_of(@_QFio_char_arrayEr) : !fir.ref<!fir.array<2x!fir.char<1,12>>>
+! CHECK: %[[C2_SHAPE:.*]] = arith.constant 2 : index
+! CHECK: %[[C1_I64_0:.*]] = arith.constant 1 : i64
+! CHECK: %[[C1_IDX_0:.*]] = fir.convert %[[C1_I64_0]] : (i64) -> index
+! CHECK: %[[C1_I64_1:.*]] = arith.constant 1 : i64
+! CHECK: %[[C1_IDX_1:.*]] = fir.convert %[[C1_I64_1]] : (i64) -> index
+! CHECK: %[[C2_I64:.*]] = arith.constant 2 : i64
+! CHECK: %[[C2_IDX:.*]] = fir.convert %[[C2_I64]] : (i64) -> index
+! CHECK: %[[SHAPE:.*]] = fir.shape %[[C2_SHAPE]] : (index) -> !fir.shape<1>
+! CHECK: %[[SLICE:.*]] = fir.slice %[[C1_IDX_0]], %[[C2_IDX]], %[[C1_IDX_1]] : (index, index, index) -> !fir.slice<1>
+! CHECK: %[[BOX_R:.*]] = fir.embox %[[R]](%[[SHAPE]]) [%[[SLICE]]] : (!fir.ref<!fir.array<2x!fir.char<1,12>>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<2x!fir.char<1,12>>>
+! CHECK: %[[BOX_R_NONE:.*]] = fir.convert %[[BOX_R]] : (!fir.box<!fir.array<2x!fir.char<1,12>>>) -> !fir.box<none>
+! CHECK: %[[DATA:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref<!fir.char<1,14>>
+! CHECK: %[[DATA_PTR:.*]] = fir.convert %8 : (!fir.ref<!fir.char<1,14>>) -> !fir.ref<i8>
+! CHECK: %{{.*}} = fir.call @_FortranAioBeginInternalArrayFormattedOutput(%[[BOX_R_NONE]], %[[DATA_PTR]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) : (!fir.box<none>, !fir.ref<i8>, i64, !fir.box<none>, !fir.ref<!fir.llvm_ptr<i8>>, i64, !fir.ref<i8>, i32) -> !fir.ref<i8>


        


More information about the flang-commits mailing list