f18-llvm-project icon indicating copy to clipboard operation
f18-llvm-project copied to clipboard

FLUSH intrinsic vs. statement link failure

Open pmccormick opened this issue 3 years ago • 12 comments

The Cloverleaf proxy app uses an pre-Fortran 2003 invocation of FLUSH that fails at link time.

    CALL FLUSH(0)
    CALL FLUSH(6)
    CALL FLUSH(g_out)
$ make COMPILER=GNU MPI_COMPILER=flang-new C_MPI_COMPILER=clang
... 
cloverleaf/CloverLeaf_Serial/./clover.f90:60: undefined reference to `_QPflush'
cloverleaf/CloverLeaf_Serial/./clover.f90:61: undefined reference to `_QPflush'
/usr/bin/ld: cloverleaf/CloverLeaf_Serial/./clover.f90:62: undefined reference to `_QPflush'
...

Removing CALL from the snippet of code above will provide a workaround but for backwards compatibility it appears that CALL FLUSH needs to be lowered as an intrinsic (or a FLUSH statement).

pmccormick avatar Dec 07 '21 19:12 pmccormick

Per Peter: Standard Fortran has a FLUSH statement but not a FLUSH intrinsic.

svedan avatar Dec 07 '21 21:12 svedan

Workaround:

SUBROUTINE FLUSH(n) FLUSH n END

svedan avatar Dec 07 '21 21:12 svedan

Just a note: other Fortran compilers (e.g. gfortran) happily deal with this convention (no workarounds needed). If we want to support/claim gfortran compatibility we should come up with a solution that doesn't require application level code changes.

pmccormick avatar Dec 07 '21 21:12 pmccormick

Peter - Comments?

svedan avatar Dec 07 '21 21:12 svedan

At this time we can't yet put Fortran code into the runtime, since we can't build it yet with the Fortran compiler you can build from llvm-project. There's a bunch of things that need to be in the runtime that would be best written in Fortran (like this compatibility extension, and many procedures in the IEEE intrinsic module). So my strategy, such as it is, has been to wait for Fortran to be a language option when we can wait. If you need this now, though, we can take another route: either coding a trampoline to the FLUSH I/O support in the runtime in C with a Fortran-mangled entry point name, or adding it to the intrinsic table as a supported extension.

klausler avatar Dec 07 '21 21:12 klausler

However, and I should have made this more clear, I believe that f18 should support this and other extensions; we want to be very easy to port to. The work-around that I gave to Sam was to get you past this problem, if you like, and proceed to build the rest of cloverleaf.

klausler avatar Dec 07 '21 21:12 klausler

The easiest workaround it simply remove CALL and then it compiles as a statement.

I completely agree with your longer-term approach but it would be good (for various reasons) to get things like Cloverleaf running "as is". I'm happy to take a shot at the intrinsic path here (given I understand that part of the code base). I can then look forward to seeing it removed at some point down the road.

Sound reasonable?

pmccormick avatar Dec 07 '21 21:12 pmccormick

I think it would actually be easier to add a C-coded routine with a Fortran-like entry point name to the runtime. It would be short and quick to write, at least for me. Adding intrinsics to the compiler involves the intrinsic table (pretty easy) and lowering (less so), and would either have to lower to the sequence of calls used for a FLUSH statement or to a new runtime entry point that would be more or less identical to the first option above anyway. So I'll go do this right now.

klausler avatar Dec 07 '21 21:12 klausler

Thanks Peter.

pmccormick avatar Dec 07 '21 21:12 pmccormick

https://reviews.llvm.org/D115289

klausler avatar Dec 07 '21 22:12 klausler

This now does the expected thing when compiled with fir-dev and a patched runtime:

      write(0,*) 'before print'
      flush 0
      print *, 'print'
      write(0,*) 'before flush'
      flush 0
      call flush(6)
      write(0,*) 'after flush'
      flush 0
      end

klausler avatar Dec 07 '21 23:12 klausler

Integrated into llvm-project/main.

klausler avatar Dec 08 '21 16:12 klausler