Wrong primitive names in LLVM I/O
jiribenes opened this issue · comments
Description
When I try to read from a file:
// repro.effekt
import io
import io/error
import io/files
def main() = eventloop(box {
with on[IOError].panic;
with filesystem;
val contents = do readFile("repro.effekt")
println(contents)
})
I get the following error:
bash-5.2$ effekt --backend=llvm repro.effekt
opt: ./out/repro.ll:1114:17: error: use of undefined value '@writeFile'
call void @writeFile(i32 %fd_int, %Pos %buffer, i64 noundef %offset, ptr %onSuccess_ptr, ptr %onFailure_ptr) #0
^
Exception in thread "main" java.lang.RuntimeException: Nonzero exit value: 1
[...]
Investigation 🔍
Upon taking a closer look at ./out/repro.ll
, I can see that writeFile
is truly neither defined nor declared there.
This happens even when I try to first build, then run.
If I had to guess, then the real name we're looking for is c_file_read
in llvm/io.c
Line 476 in cd741e8
which got renamed at the end of #469.
When investigating this, I also noticed that the LLVM definition corresponds to the C definition only with the ARM64 calling convention:
Line 13 in cd741e8
I think it should be something like declare void @c_file_write(i32, %Pos, i64, %Neg*, %Neg*)
instead? (or ptr, ptr
for the last two, not sure)
I'm quite alarmed that the test in stdlib/io/files/async_file_io.effekt
didn't catch this 🤔
https://github.com/effekt-lang/effekt/blob/cd741e8a4576c62ab318efd48fc0831958ba7e8d/examples/stdlib/io/files/async_file_io.effekt
EDIT: I tried running the LLVM stdlib tests and it appears that the test in question passes:
effekt.StdlibLLVMTests:
+ examples/stdlib/bytes/bytes.effekt (llvm) 2.928s
+ examples/stdlib/io/promise.effekt (llvm) 1.146s
+ examples/stdlib/io/files/async_file_io.effekt (llvm) 1.416s
The test works when ran directly:
$ effekt --backend=llvm examples/stdlib/io/files/async_file_io.effekt
Running program
Done
Some contents
{ msg: "Hello World!" }
done reading files.
but I don't understand why 😔
Well, the test only uses the readFile
function and not the readFile
operation which is then handled with filesystem
. If I had to guess, the renaming is OK in one of them and not in the other...
It's writeFile, isn't it? Since we don't write files in the test, dead code elimination removes it before it causes problems