[flang-commits] [flang] 76fd4bf - [Flang] Finalize IO operations after calling EndIO

Peter Steinfeld via flang-commits flang-commits at lists.llvm.org
Thu Sep 22 07:24:08 PDT 2022


Author: Peter Steinfeld
Date: 2022-09-22T07:13:03-07:00
New Revision: 76fd4bf675b5ceeeca0e4e15cf15d89c7acf4947

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

LOG: [Flang] Finalize IO operations after calling EndIO

The process of passing arguments to IO calls can cause allocations that
get referenced during EndIO calls.  Calling "Finalize" causes these
allocations to be deallocated.  This means that references to them in
the code in EndIO will be invalid.  The fix is to delay the call to
"finalize" until after the call to EndIO.

This particularly causes problems with the IO items are strings that are
produced by calls to functions.

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

Added: 
    flang/test/Lower/io-write.f90

Modified: 
    flang/lib/Lower/IO.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp
index 14642146df015..505a2d7486288 100644
--- a/flang/lib/Lower/IO.cpp
+++ b/flang/lib/Lower/IO.cpp
@@ -1989,7 +1989,6 @@ genDataTransferStmt(Fortran::lower::AbstractConverter &converter,
                       csi.hasTransferConditionSpec(), ok,
                       /*inLoop=*/false);
   }
-  stmtCtx.finalize();
 
   builder.restoreInsertionPoint(insertPt);
   if constexpr (hasIOCtrl) {
@@ -1997,7 +1996,9 @@ genDataTransferStmt(Fortran::lower::AbstractConverter &converter,
                   csi.hasErrorConditionSpec());
   }
   // Generate end statement call/s.
-  return genEndIO(converter, loc, cookie, csi, stmtCtx);
+  mlir::Value result = genEndIO(converter, loc, cookie, csi, stmtCtx);
+  stmtCtx.finalize();
+  return result;
 }
 
 void Fortran::lower::genPrintStatement(

diff  --git a/flang/test/Lower/io-write.f90 b/flang/test/Lower/io-write.f90
new file mode 100644
index 0000000000000..fa1424e710c51
--- /dev/null
+++ b/flang/test/Lower/io-write.f90
@@ -0,0 +1,42 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+! Test that IO item calls stackrestore in the right place 
+
+! CHECK-LABEL: func.func @_QQmain() {
+  character(3) string
+  write(string,getstring(6))
+! CHECK:  %[[Val_0:.*]] = fir.alloca i32 {adapt.valuebyref}
+! CHECK:  %[[Val_1:.*]] = fir.address_of(@_QFEstring) : !fir.ref<!fir.char<1,3>>
+! CHECK:  %[[Const_3:.*]] = arith.constant 3 : index
+! CHECK:  %[[Val_2:.*]] = fir.convert %[[Val_1]] : (!fir.ref<!fir.char<1,3>>) -> !fir.ref<i8>
+! CHECK:  %[[Val_3:.*]] = fir.convert %[[Const_3]] : (index) -> i64
+! CHECK:  %[[Const_6:.*]] = arith.constant 6 : i32
+! CHECK:  fir.store %[[Const_6]] to %[[Val_0]] : !fir.ref<i32>
+! CHECK:  %[[Val_4:.*]] = fir.load %[[Val_0]] : !fir.ref<i32>
+! CHECK:  %[[Val_5:.*]] = fir.convert %[[Val_4]] : (i32) -> i64
+! CHECK:  %[[Val_6:.*]] = fir.convert %[[Val_5]] : (i64) -> index
+! CHECK:  %[[Const_0:.*]] = arith.constant 0 : index
+! CHECK:  %[[Val_7:.*]] = arith.cmpi sgt, %[[Val_6]], %[[Const_0]] : index
+! CHECK:  %[[Val_8:.*]] = arith.select %[[Val_7]], %[[Val_6]], %[[Const_0]] : index
+! CHECK:  %[[Val_9:.*]] = fir.call @llvm.stacksave() : () -> !fir.ref<i8>
+! CHECK:  %[[Val_10:.*]] = fir.alloca !fir.char<1,?>(%[[Val_8]] : index) {bindc_name = ".result"}
+! CHECK:  %[[Val_11:.*]] = fir.call @_QFPgetstring(%[[Val_10]], %[[Val_8]], %[[Val_0]]) : (!fir.ref<!fir.char<1,?>>, index, !fir.ref<i32>) -> !fir.boxchar<1>
+! CHECK:  %[[Val_12:.*]] = fir.convert %[[Val_10]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
+! CHECK:  %[[Val_13:.*]] = fir.convert %[[Val_8]] : (index) -> i64
+! CHECK:  %[[Val_14:.*]] = fir.zero_bits !fir.box<none>
+! CHECK:  %[[Const_0_i64:.*]] = arith.constant 0 : i64
+! CHECK:  %[[Val_15:.*]] = fir.convert %[[Const_0_i64]] : (i64) -> !fir.ref<!fir.llvm_ptr<i8>>
+! CHECK:  %[[Const_0_i64_0:.*]] = arith.constant 0 : i64
+! CHECK:  %[[Val_16:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
+! CHECK:  %[[Val_17:.*]] = fir.convert %[[Val_16]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+! CHECK:  %[[Val_18:.*]] = fir.call @_FortranAioBeginInternalFormattedOutput(%[[Val_2]], %[[Val_3]], %[[Val_12]], %[[Val_13]],
+! %[[Val_14]], %[[Val_15]], %[[Const_0_i64_0]], %17, %{{.*}}) : (!fir.ref<i8>, i64, !fir.ref<i8>, i64, !fir.box<none>, !fir.ref<!fir.llvm_ptr<i8>>, i64, !fir.ref<i8>, i32) -> !fir.ref<i8>
+! CHECK:  %[[Val_19:.*]] = fir.call @_FortranAioEndIoStatement(%18) : (!fir.ref<i8>) -> i32
+! CHECK:  fir.call @llvm.stackrestore(%[[Val_9]]) : (!fir.ref<i8>) -> ()
+  if (string/="hi") stop 'FAIL'
+contains
+  function getstring(n) result(r)
+    character(n) r
+    r = '("hi")'
+  end function
+end


        


More information about the flang-commits mailing list