diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index 13872b29322a3..7a19b34bd6824 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -32,6 +33,7 @@ #include #include #include +#include #include #include #if defined(USE_POLLY) @@ -434,6 +436,23 @@ static void reportWriterError(const ErrorInfoBase &E) jl_safe_printf("ERROR: failed to emit output file %s\n", err.c_str()); } +static void injectCRTAlias(Module &M, StringRef name, StringRef alias, FunctionType *FT) +{ + Function *target = M.getFunction(alias); + if (!target) { + target = Function::Create(FT, Function::ExternalLinkage, alias, M); + } + Function *interposer = Function::Create(FT, Function::WeakAnyLinkage, name, M); + appendToCompilerUsed(M, {interposer}); + + llvm::IRBuilder<> builder(BasicBlock::Create(M.getContext(), "top", interposer)); + SmallVector CallArgs; + for (auto &arg : interposer->args()) + CallArgs.push_back(&arg); + auto val = builder.CreateCall(target, CallArgs); + builder.CreateRet(val); +} + // takes the running content that has collected in the shadow module and dump it to disk // this builds the object file portion of the sysimage files for fast startup @@ -550,7 +569,24 @@ void jl_dump_native_impl(void *native_code, auto add_output = [&] (Module &M, StringRef unopt_bc_Name, StringRef bc_Name, StringRef obj_Name, StringRef asm_Name) { preopt.run(M); optimizer.run(M); + + // We would like to emit an alias or an weakref alias to redirect these symbols + // but LLVM doesn't let us emit a GlobalAlias to a declaration... + // So for now we inject a definition of these functions that calls our runtime + // functions. We do so after optimization to avoid cloning these functions. + injectCRTAlias(M, "__gnu_h2f_ieee", "julia__gnu_h2f_ieee", + FunctionType::get(Type::getFloatTy(Context), { Type::getHalfTy(Context) }, false)); + injectCRTAlias(M, "__extendhfsf2", "julia__gnu_h2f_ieee", + FunctionType::get(Type::getFloatTy(Context), { Type::getHalfTy(Context) }, false)); + injectCRTAlias(M, "__gnu_f2h_ieee", "julia__gnu_f2h_ieee", + FunctionType::get(Type::getHalfTy(Context), { Type::getFloatTy(Context) }, false)); + injectCRTAlias(M, "__truncsfhf2", "julia__gnu_f2h_ieee", + FunctionType::get(Type::getHalfTy(Context), { Type::getFloatTy(Context) }, false)); + injectCRTAlias(M, "__truncdfhf2", "julia__truncdfhf2", + FunctionType::get(Type::getHalfTy(Context), { Type::getDoubleTy(Context) }, false)); + postopt.run(M); + if (unopt_bc_fname) emit_result(unopt_bc_Archive, unopt_bc_Buffer, unopt_bc_Name, outputs); if (bc_fname)