는 다음과 같은 프로그램을 고려 :엄격한 앨리어싱, -ffast - 수학 및 SSE
$ clang --version
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin14.5.0
Thread model: posix
$ clang test.cpp -o test
$ ./test
0 0 0 0
$ clang test.cpp -ffast-math -o test
$ ./test
0 0 0 0
:
#include <iostream>
#include <cmath>
#include <cstring>
#include <xmmintrin.h>
using namespace std;
int main()
{
// 4 float32s.
__m128 nans;
// Set them all to 0xffffffff which should be NaN.
memset(&nans, 0xff, 4*4);
// cmpord should return a mask of 0xffffffff for any non-NaNs, and 0x00000000 for NaNs.
__m128 mask = _mm_cmpord_ps(nans, nans);
// AND the mask with nans to zero any of the nans. The result should be 0x00000000 for every component.
__m128 z = _mm_and_ps(mask, nans);
cout << z[0] << " " << z[1] << " " << z[2] << " " << z[3] << endl;
return 0;
}
내가 함께하고 -ffast-math
없이 애플 연타 7.0.2 컴파일하는 경우를, 내가 예상 출력 0 0 0 0
를 얻을 수
그러나 8.1.0으로 업데이트 한 후 (죄송합니다. 어떤 실제 버전의 Clang인지 알 수 없습니다. Apple이 더 이상 해당 정보를 게시하지 않음) -ffast-math
은 이것을 깨뜨린 것으로 보입니다.
$ clang --version
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ clang test.cpp -o test
$ ./test
0 0 0 0
$ clang test.cpp -ffast-math -o test
$ ./test
nan nan nan nan
엄격한 앨리어싱 규칙 또는 그와 유사한 것으로 판단됩니다. 아무도이 동작을 설명 할 수 있습니까?
편집 : 나는 당신이 nans = { std::nanf(nullptr), ...
을하면 잘 작동한다고 언급하는 것을 잊어 버렸습니다.
또한을 보면 Clang 3.8.1과 Clang 3.9 사이에서 동작이 변경된 것 같습니다. 후자는 cmpordps
명령을 제거합니다. GCC 7.1은 그것을 그대로두고있는 것 같습니다.
허 나는 그것을 몰랐다. .. 고마워! – Timmmm