Closed Astavie closed 2 years ago
It seems these functions are part of compiler-rt / libgcc
EDIT: they usually are, but it seems odin also defines them internally
Doing more research...
llvm generates a call to __truncdfhf2
when encountering trunc i128
, which is used in @strconv.append_bits_128
among other places
These processes are defined in core:runtime/internal.odin
When optimalization is off, these can even be seen in the .ll file:
...
define internal i16 @__truncdfhf2(double %0) {
decls:
br label %entry
entry: ; preds = %decls
%1 = fptrunc double %0 to float
%2 = call i16 @__truncsfhf2(float %1)
ret i16 %2
}
...
However, turning optimalization on removes them from the .ll file. My theory is now that llvm removes them as they are deemed unused?
Theory likely true: compiling on linux with odin build . -no-crt -o:speed
gives a linking error:
odin_package:(.text+0x2466f): undefined reference to `__truncdfhf2'
Of course, this will never be able to run either way because of -no-crt
, but it does sort of compile if you remove the -o:speed
flag.
So in summary, llvm generates calls to specific functions when encountering some operators with 128-bit operands. These are usually defined in compiler-rt / libgcc, but not every architecture has those libraries. I assume this is why odin also defines these functions itself in core:runtime/internal.odin.
However, right now this only seems to work at the lowest settings of optimization where LLVM does not remove unused definitions. In other cases, these internally-defined procs get removed before they are linked. This usually goes unnoticed since they then get linked to compiler-rt / libgcc.
The error happens when odin builds with high optimization and without being linked to the C Run Time, which happens when building to WebAssembly or enabling the -no-crt
flag.
This could potentially be fixed by adding the procs inside internal.odin to the ‘llvm.compiler.used’ Global Variable, to prevent the compiler from touching them until linking. Given the amount of time I've put into this now today, I might even make my first PR.
Context
Expected Behavior
"Hellope!" to be displayed in the browser console
Current Behavior
I get the error
Uncaught (in promise) LinkError: import object field '__truncdfhf2' is not a Function
Failure Information (for bugs)
Looking inside the generated .wasm file, it seems it is expecting four functions to be defined in the
env
namespace:This happens with
-opt:1
,-opt:2
,-opt:3
,-o:size
, or-o:speed
.When looking at the output without any of these build settings, it seems these functions are simply defined internally:
Steps to Reproduce
Building it with
odin build . -target:js_wasm32 -o:size
gives a.wasm
fileTry to run the .wasm file using the following html (runtime.js grabbed from vendor:wasm)
Failure Logs