【发布时间】:2022-01-04 21:44:11
【问题描述】:
示例代码 (t0.c):
#include <stdio.h>
float f(float a, float b, float c) __attribute__((noinline));
float f(float a, float b, float c)
{
return a * c + b * c;
}
int main(void)
{
void* p = V;
printf("%a\n", f(4476.0f, 20439.0f, 4915.0f));
return 0;
}
调用和执行(通过 godbolt.org):
# icc 2021.1.2 on Linux on x86-64
$ icc t0.c -fp-model=fast -O3 -DV=f
0x1.d32322p+26
$ icc t0.c -fp-model=fast -O3 -DV=0
0x1.d32324p+26
生成的汇编代码相同:https://godbolt.org/z/osra5jfYY。
为什么生成的相同汇编代码不会导致相同的输出?
为什么void* p = f; 很重要?
【问题讨论】:
-
什么在tarnation...你确定可执行文件是相同的吗?
diff说什么? -
我还没有比较可执行文件。据我了解,godbolt.org(还)不允许下载(或在线比较)可执行文件。
-
使用调试器 - 跳过汇编代码。查看在调用
printf之前真正 包含哪些寄存器,具体取决于您在此处看不到的其他初始化代码。因此,快速数学通常会给出“有趣”的结果。 -
是的,我想知道显示的程序集是否实际上与正在执行的代码匹配。例如,也许正在发生链接时间优化?
-
啊,当你选择“编译为二进制”时检查一下。
-DV=0版本已将f减少为仅返回一个常量 - 大概是过程间常量传播,一旦链接器可以看到没有其他对f的调用就完成了。取f的地址可能会被愚弄。
标签: c floating-point x86-64 floating-accuracy icc