f18-llvm-project
f18-llvm-project copied to clipboard
FLUSH intrinsic vs. statement link failure
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).
Per Peter: Standard Fortran has a FLUSH statement but not a FLUSH intrinsic.
Workaround:
SUBROUTINE FLUSH(n) FLUSH n END
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.
Peter - Comments?
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.
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.
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?
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.
Thanks Peter.
https://reviews.llvm.org/D115289
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
Integrated into llvm-project/main.