microsoft / DirectXMath

DirectXMath is an all inline SIMD C++ linear algebra library for use in games and graphics apps
https://walbourn.github.io/introducing-directxmath/
MIT License
1.51k stars 231 forks source link

unexpected results with clang-cl /fp:fast in release mode #152

Closed UUUnmei closed 1 year ago

UUUnmei commented 1 year ago

my kits: vs2022 community 17.3.6 clang 14.0.5 (installed together with vs2022) Windows 10 Kits 10.0.19041.0

this may be more like a reminding not bug report.

first of all, here is a example to reproduce in a new project, using clang-cl, /fp:fast and compile following codes in release mode

#include <iostream>
#include <DirectXMath.h>
using namespace std;
using namespace DirectX;

int main() {
    auto vec = XMQuaternionRotationRollPitchYaw(45, 0, 0);
    XMFLOAT4 v4;
    XMStoreFloat4(&v4, vec);
    cout << v4.x << ' ' << v4.y << ' ' << v4.z << ' ' << v4.w << '\n';
    return 0;
}

expected -0.487174 0 0 -0.873305 but actually 0 0 0 1 again, i'm not targeting at that rotation funciton, i just first notice it's behaving weired in my project.(No matter how you move and drag the mouse, you can not rotate anything, crazy)

meanwhile, this code behave well with other settings, like clang-cl+/fp:fast+debug, and /fp:precise+whatever !

after some searching, i do find some issues seems relate with this. like VS2022 behavior for contractions floating-point-support-in-clang Clang changed -ffp-contract flag https://github.com/llvm/llvm-project/issues/54927

however i still not understand those things about fpcontract quite well. any other insights are welcome for now, i prefer to think of this as a bug about floating-point model or compiler optimization.

and i'm still curious about can we do something when coding to avoid this as much as possible... maybe it's also a good reason to add some tests, though thanks

walbourn commented 1 year ago

Just to clarify, the 45 literal you are passing to XMQuaternionRotationRollPitchYaw: The function takes radians, not degrees, so you are going to get something like 7 complete rotations plus a little...

If you do a rotation by XM_PI/4 (i.e. 45° expressed as radians), the answers match for MSVC, clang v15, /fp:fast, etc.

UUUnmei commented 1 year ago

oops, sorry for that... but it is still there (and not just for specific angles) does clang version make a difference?

my cli options: (and inherit from default) /GS /W3 /Gy /Zi /O2 /fp:fast /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /WX- /Gd /Oi /MD /Fa"x64\Release\" /EHsc /nologo /Fo"x64\Release\" /Fp"x64\Release\Project1.pch" /diagnostics:column (i'm not using any pch, though it does specify a name for it)

UUUnmei commented 1 year ago

https://user-images.githubusercontent.com/54660562/199638971-b30baf61-e130-4ccd-84cc-3ef7bb92ff61.mp4

walbourn commented 1 year ago

Any use of /fp:fast allows the compiler to deviate from IEEE-754 rules for floating-point, so it's not going to be consistent between compilers.

walbourn commented 1 year ago

You may also want to try the latest DirectXMath. Windows 10 SDK (19041) contains DirectXMath 3.14. You can get newer versions from GitHub, NuGet, vcpkg, or installing newer Windows SDKs.

UUUnmei commented 1 year ago

You may also want to try the latest DirectXMath. Windows 10 SDK (19041) contains DirectXMath 3.14. You can get newer versions from GitHub, NuGet, vcpkg, or installing newer Windows SDKs.

i tried ver3.17 through vcpkg, but it still not works unfortunately. anyway, thank you very much let's looking forward to a better collaboration between compilers in the future xD