[flang-commits] [flang] [Flang] add support for collapsed io calls for implicit do loops (PR #212646)

via flang-commits flang-commits at lists.llvm.org
Wed Jul 29 02:00:50 PDT 2026


================
@@ -701,6 +701,244 @@ static mlir::func::FuncOp getOutputFunc(mlir::Location loc,
                                                                    builder);
 }
 
+/// Return the evaluate expression of a non-implied-do io item, or nullptr if
+/// the item is itself an io-implied-do.
+static const Fortran::lower::SomeExpr *
+getIoItemLeafExpr(const Fortran::parser::OutputItem &item) {
+  if (const auto *parserExpr = std::get_if<Fortran::parser::Expr>(&item.u))
+    return Fortran::semantics::GetExpr(*parserExpr);
+  return nullptr;
+}
+static const Fortran::lower::SomeExpr *
+getIoItemLeafExpr(const Fortran::parser::InputItem &item) {
+  if (const auto *var = std::get_if<Fortran::parser::Variable>(&item.u))
+    return Fortran::semantics::GetExpr(*var);
+  return nullptr;
+}
+
+template <typename A>
+static bool ioExprReferencesSymbol(const A &expr,
+                                   const Fortran::semantics::Symbol &sym) {
+  const Fortran::semantics::Symbol &ultimate = sym.GetUltimate();
+  for (const Fortran::semantics::SymbolRef &ref :
+       Fortran::evaluate::CollectSymbols(expr)) {
+    if (&ref->GetUltimate() == &ultimate)
+      return true;
+  }
+  return false;
+}
----------------
jeanPerier wrote:

I think for all the following case, it is illegal to do the transformation for instance:

```
subroutine test1()
 integer :: a(8), i
 equivalence (i, a(4))
 a = 0
 print *, "equivalence test"
 write (6,*) (a(i), i=1,8)
 end subroutine

 subroutine test2()
 integer, target :: a(8)
 integer, pointer :: i
 i => a(4) 
 a = 0
 print *, "pointer test"
 write (6,*) (a(i), i=1,8)
 end subroutine

 subroutine test3()
 integer :: a(8)
   associate (i => a(4)) 
     a = 0
     print *, "associate test"
     write (6,*) (a(i), i=1,8)
   end associate
 end subroutine

  subroutine test4()
   integer :: b(8)
   b = 0
   call sub(b, b(4))
   contains
   subroutine sub(a, i)
     integer :: a(8), i
     print *, "dummy association test"
     write (6,*) (a(i), i=1,8)
   end subroutine
 end subroutine

 call test1()
 call test2()
 call test3()
 call test4()
 end
```

As far as I see the standard does not forbid the io-implied do-variable from being associated to output items (this is not true for input item). However, with input item, there could be some other tricky cases like `read (10) (a(i, p), i=1,10)` where `p` may be associated to one of the `a(i, j)` being read. So my comment applies to all the usages of ioExprReferencesSymbol.

https://github.com/llvm/llvm-project/pull/212646


More information about the flang-commits mailing list