我试图理解为什么 Clang 将一个函数参数(一个全局变量)编译成一个内联 Bitcast 指令。 有没有办法将这个内联指令从函数调用提升到调用者函数的主体? 这是我使用 Clang(版本 6 和 8)将以下 C 编译为 LLVM IR 的示例程序。 # File name: global-tes ...
提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供 中文繁体 英文版本 中英对照 版本,有任何建议请联系yoyou2525@163.com。
我正在评估性能关键/“热”代码中浮点异常的使用(清除和查询)。 查看生成的二进制文件,我注意到 GCC 和 Clang 都没有将调用扩展为我期望的内联指令序列; 相反,它们似乎生成了对运行时库的调用。 这对于我的应用程序来说是非常昂贵的。
考虑以下最小示例:
#include <fenv.h>
#pragma STDC FENV_ACCESS on
inline int fetestexcept_inline(int e)
{
unsigned int mxcsr;
asm volatile ("vstmxcsr" " %0" : "=m" (*&mxcsr));
return mxcsr & e & FE_ALL_EXCEPT;
}
double f1(double a)
{
double r = a * a;
if(r == 0 || fetestexcept_inline(FE_OVERFLOW)) return -1;
else return r;
}
double f2(double a)
{
double r = a * a;
if(r == 0 || fetestexcept(FE_OVERFLOW)) return -1;
else return r;
}
以及 GCC 产生的输出: https : //godbolt.org/z/jxjzYY
编译器似乎知道他可以对目标使用依赖于 CPU 系列的 AVX 指令(它使用“vmulsd”进行乘法)。 但是,无论我尝试使用哪种优化标志,它总是会产生对 glibc 的更昂贵的函数调用,而不是(据我所知)应该执行相应 glibc 函数所做的程序集。
这不是为了抱怨,我可以添加内联程序集。 我只是想知道是否存在我忽略的细微差别,这可能是内联汇编版本中的错误。
它需要支持long double
算术。 fetestexcept
需要合并 SSE 和 FPU 状态,因为long double
操作只更新 FPU 状态,而不是 MXSCR 寄存器。 因此,内联的好处有所减少。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.