概括
最近我遇到了一個關于 LTO 的奇怪問題,-ffast-math我的“pow”(in cmath)呼叫結果不一致,具體取決于是否-flto使用。
環境:
$ g --version
g (GCC) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ ll /lib64/libc.so.6
lrwxrwxrwx 1 root root 12 Sep 3 2019 /lib64/libc.so.6 -> libc-2.17.so
$ ll /lib64/libm.so.6
lrwxrwxrwx 1 root root 12 Sep 3 2019 /lib64/libm.so.6 -> libm-2.17.so
$ cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
最小的例子
代碼
fixed.hxx
#include <cstdint>
double Power10f(const int16_t power);
fixed.cxx
#include "fixed.hxx"
#include <cmath>
double Power10f(const int16_t power)
{
return pow(10.0, (double) power);
}
test.cxx
#include <iostream>
#include <cmath>
#include <iomanip>
#include <cstdint>
#include "fixed.hxx"
int main(int argc, char** argv)
{
if (argc >= 3) {
int64_t value = (int64_t)atoi(argv[1]);
int16_t power = (int16_t)atoi(argv[2]);
double x = Power10f(power);
std::cout.precision(17);
std::cout << std::scientific << x << std::endl;
std::cout << std::scientific << (double)value * x << std::endl;
return 0;
}
return 1;
}
編譯并運行
-ffast-math使用和使用/不編譯它-flto會給出不同的結果
- With
-flto最終會呼叫__pow_finite版本并給出“準確”的結果:
$ g -O3 -DNDEBUG -ffast-math -std=c 17 -flto -o fixed.cxx.o -c fixed.cxx
$ g -O3 -DNDEBUG -o fdtest fixed.cxx.o test.cxx
$ ./fdtest 81 20
1.00000000000000000e 20
8.10000000000000000e 21
$ objdump -DC fdtest > fdtest.dump
$ cat fdtest.dump
...
0000000000400930 <Power10f(short)>:
400930: 0f bf ff movswl %di,
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/496789.html
