LLVM JIT fabsf 在使用 powf 时解决错误
LLVM JIT fabsf resolve error when using powf
我正在试验 LLVM 的 JIT 功能,在调用 powf
时我观察到如果我简单地为它添加一个声明,调用 powf
就可以工作
declare float @powf(float, float))
并用两个变量调用它
%4 = call float @powf(float %3, float %2)
然而,当我用 0.5
的常数指数做同样的事情时
%4 = call float @powf(float %3, float 5.000000e-01)
失败并出现以下错误:
LLVM ERROR: Program used external function 'fabsf' which could not be resolved!
powf
调用被以下优化过程替换,所以我知道 fabsf
来自哪里:
%sqrtf = tail call float @sqrtf(float %3) #1
%fabsf = tail call float @fabsf(float %sqrtf) #1
%4 = fcmp oeq float %3, 0xFFF0000000000000
%5 = select i1 %4, float 0x7FF0000000000000, float %fabsf
我尝试在外部注册 fabsf
(但显然不正确),但这没有用:
auto float_type = llvm::Type::getFloatTy(context);
std::vector<llvm::Type *> unary_arg_types(1, float_type);
auto unary_op_type = llvm::FunctionType::get(float_type, unary_arg_types, false);
auto fabsf_llvm = llvm::Function::Create(unary_op_type, llvm::Function::ExternalLinkage, "fabsf", module);
ee->addGlobalMapping(fabsf_llvm, reinterpret_cast<void *>(&::fabsf));
我在 Windows 7 上使用 MCJIT ExecutionEngine 和 运行 以及 LLVM 和我用 MinGW 编译的测试程序。
问题一:如何注册fabsf
才不会出现这个错误?
问题2:为什么这里需要fabsf
?
编辑: 看来我偶然发现了一个(已知的)MCJIT 错误:http://llvm.org/bugs/show_bug.cgi?id=20656
是的,这是 MCJIT 中的一个已知错误。
我在 LLVMDev 邮件列表上偶然发现了一个解决方案。
您可以使用位于 llvm/Support/DynamicLibrary.h
header 中的 llvm::sys::DynamicLibrary::AddSymbol()
来注册您丢失的符号。这是您问题 1 的答案。
对于问题2:(免责声明:我不是浮点专家,不知道我在这里写的内容是否属实)
由于 powf
被转换为 sqrtf
当 sqrtf
的结果未定义时,您将得到一个 QNaN(安静的 NaN),因为提供了否定参数。在 ISO 754 中,QNaN
表示为 0xFFF0000000000000
或 0x7FF0000000000000
(符号与 ISO 754 中的 QNaN
无关)。
在 C++ 中,pow
的定义如下:
pow(base, exp) returns NaN and raises FE_INVALID if base is finite and
negative and exp is finite and non-integer.
...
pow(±0, exp), where exp is positive non-integer or a positive even
integer, returns +0
请注意,它每次都会 return 正值 0
。
但是 sqrt
:
If the argument is +∞ or ±0, it is returned, unmodified.
最后回答您的问题:在您的情况下,fabsf
有必要摆脱 sqrt
保留而 pow
将其丢弃的标志。
我正在试验 LLVM 的 JIT 功能,在调用 powf
时我观察到如果我简单地为它添加一个声明,调用 powf
就可以工作
declare float @powf(float, float))
并用两个变量调用它
%4 = call float @powf(float %3, float %2)
然而,当我用 0.5
%4 = call float @powf(float %3, float 5.000000e-01)
失败并出现以下错误:
LLVM ERROR: Program used external function 'fabsf' which could not be resolved!
powf
调用被以下优化过程替换,所以我知道 fabsf
来自哪里:
%sqrtf = tail call float @sqrtf(float %3) #1
%fabsf = tail call float @fabsf(float %sqrtf) #1
%4 = fcmp oeq float %3, 0xFFF0000000000000
%5 = select i1 %4, float 0x7FF0000000000000, float %fabsf
我尝试在外部注册 fabsf
(但显然不正确),但这没有用:
auto float_type = llvm::Type::getFloatTy(context);
std::vector<llvm::Type *> unary_arg_types(1, float_type);
auto unary_op_type = llvm::FunctionType::get(float_type, unary_arg_types, false);
auto fabsf_llvm = llvm::Function::Create(unary_op_type, llvm::Function::ExternalLinkage, "fabsf", module);
ee->addGlobalMapping(fabsf_llvm, reinterpret_cast<void *>(&::fabsf));
我在 Windows 7 上使用 MCJIT ExecutionEngine 和 运行 以及 LLVM 和我用 MinGW 编译的测试程序。
问题一:如何注册fabsf
才不会出现这个错误?
问题2:为什么这里需要fabsf
?
编辑: 看来我偶然发现了一个(已知的)MCJIT 错误:http://llvm.org/bugs/show_bug.cgi?id=20656
是的,这是 MCJIT 中的一个已知错误。
我在 LLVMDev 邮件列表上偶然发现了一个解决方案。
您可以使用位于 llvm/Support/DynamicLibrary.h
header 中的 llvm::sys::DynamicLibrary::AddSymbol()
来注册您丢失的符号。这是您问题 1 的答案。
对于问题2:(免责声明:我不是浮点专家,不知道我在这里写的内容是否属实)
由于 powf
被转换为 sqrtf
当 sqrtf
的结果未定义时,您将得到一个 QNaN(安静的 NaN),因为提供了否定参数。在 ISO 754 中,QNaN
表示为 0xFFF0000000000000
或 0x7FF0000000000000
(符号与 ISO 754 中的 QNaN
无关)。
在 C++ 中,pow
的定义如下:
pow(base, exp) returns NaN and raises FE_INVALID if base is finite and negative and exp is finite and non-integer.
...
pow(±0, exp), where exp is positive non-integer or a positive even integer, returns +0
请注意,它每次都会 return 正值 0
。
但是 sqrt
:
If the argument is +∞ or ±0, it is returned, unmodified.
最后回答您的问题:在您的情况下,fabsf
有必要摆脱 sqrt
保留而 pow
将其丢弃的标志。