如何查看内置函数的汇编输出?Godbolt使用疑问
关于Godbolt中round内置函数汇编代码的疑问
我尝试用Godbolt在线编译器查看内置函数生成的汇编代码,示例代码如下:
#include <cmath> double br( double x ) { return __builtin_roundl(x); } double r( double x ) { return std::round( x ); }
得到的汇编输出仅为:
br(double): jmp round r(double): jmp round
我推测存在能显示内置函数定义的编译器参数,但没找到合适选项,想了解两个问题:
- 这个函数最终会生成什么代码?
- 是否有办法将round的调用内联?
解答
为什么当前输出是跳转指令?
默认情况下,GCC等编译器会将std::round和__builtin_roundl(注:你的函数参数是double,__builtin_roundl是long double版本,编译器会做隐式转换,换成__builtin_round更匹配)映射到系统库中的round函数,不会展开具体实现,所以汇编只生成跳转指令。
查看实际生成的代码并实现内联
要让编译器内联round的实现并生成具体汇编,需要添加以下编译器参数:
-ffast-math:该参数会禁用数学异常检查、允许浮点运算的近似优化,让编译器直接生成内联的浮点指令,而不是调用外部库函数。-march=<架构>:比如-march=skylake或-march=native,确保编译器生成对应CPU架构支持的高级浮点指令(如SSE4.1、AVX等)。
添加-ffast-math -march=skylake -O3参数后,生成的汇编会变成内联指令:
br(double): roundsd $1, %xmm0, %xmm0 ret r(double): roundsd $1, %xmm0, %xmm0 ret
这里的roundsd是x86 SSE4.1指令集提供的双精度round指令,直接在XMM寄存器上完成浮点取整操作,无需调用外部函数。
如果不想使用-ffast-math(因为它会改变浮点语义),可以尝试-O3 -fno-math-errno参数,部分场景下编译器也会内联round实现,但效果不如-ffast-math彻底,因为后者允许更多优化空间。
内容的提问来源于stack exchange,提问作者mkluwe
相关产品推荐
相关产品推荐

