JIT compiled intrinsics calls is call to null pointer

Hi everyone,

I am trying to call an LLVM intrinsic (llvm.pow.f32), inserted with the following call:

std::vector<llvm::Type *> arg_types;
arg_types.push_back(llvm::Type::getFloatTy(context));
auto function=llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::pow, arg_types);

auto result=ir_builder->CreateCall(function, args);

When I try to execute the code generated by the JIT compiler, I see that the intrinsic is not compiled into a math coprocessor instruction, but in a call to a null address:

002300B8 sub esp,8

002300BB movss xmm0,dword ptr ds:[2300B0h]
002300C3 movss dword ptr [esp+4],xmm0
002300C9 movss xmm0,dword ptr ds:[2300B4h]
002300D1 movss dword ptr [esp],xmm0
002300D6 call 00000000
002300DB add esp,8
002300DE ret

Is there anything special that I need to do in order to be able to call intrinsics, either in general or when JITting? I am either doing something wrong, or forgetting to do something, but I don’t know what.

I am working with a Visual Studio compiled version on Windows (x86).

All hints will be appreciated, with kind regards,

Taco H. in den Bosch.

Hi Taco,

We had a similar issue where a math intrinsic was being converted to a call to null and it turned out to be because the system didn’t support the CPU instructions for the operation so the intrinsic used a call to the library function (pow in your case). However because we weren’t expecting this math function to be looked up by MCJIT in our JITMemoryManager::getPointerToNamedFunction() we weren’t making it available and it was returning null.

Not sure if this is relevant to your case but maybe it’ll help point you in the right direction.

Cheers,
Andrew

Hi Taco,
I think I know what is happening here, I ran into it not too long ago.
if you are calling pow with a base of 2, e.g. pow(2.0f, x), then LLVM will try and optimise it to exp2f(x).
However exp2f doesn't exist on windows.
LLVM *should* know this, but it requires that you tell the target triple to the optimisation passes, something like:

fpm.add(new llvm::TargetLibraryInfo(llvm::Triple(this->triple)));

This requirement is undocumented.

Even doing this, the issue will still occur in LLVM 3.3, but is fixed in trunk.
For this reason powf() is the only intrinsic I don't use yet, I just use a call to the library function.

Cheers,
     Nick

Nicholas Chapman

Managing Director,
Glare Technologies Limited