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.53k stars 235 forks source link

Crash in XMVector3Unproject / XMMatrixMultiply #57

Closed nasenbaer43 closed 6 years ago

nasenbaer43 commented 6 years ago

Hi, I'm getting crashes in XMVector3Unproject although I'm only using stack allocated variables, e.g. NO XMVECTOR or XMMATRIX as a member variable (see Test3() below). I tried both WinSDKs 8.1 and the newest 10.xyz one, DirectXMath version 310 / 307. Haven't tried your newest github one yet. Compiler is VS 2017 Enterprise 15.3. Debug x86 native Win32.

Here is a small repro ( I also attached the repro as a solution)

#include "stdafx.h"
#include <DirectXMath.h>

#pragma comment(lib, "d3d11.lib")

/*#pragma pack(push)
#pragma pack(16)

// Please note this is just a test. I'm not storing any aligned vars in my real code. My real usage is seen in Test3()
__declspec(align(16)) struct TestStruct {
    DirectX::XMMATRIX identity = DirectX::XMMatrixIdentity();;
    DirectX::XMVECTOR mousepos1 = DirectX::XMVectorSet(400.0f, 200.0f, 0.00999999978f, 0);
} g_TestStruct;

#pragma pack(pop)*/

void Test1() {
    DirectX::XMMATRIX identity = DirectX::XMMatrixIdentity();
    DirectX::XMVECTOR mousepos1 = DirectX::XMVectorSet(400.0f, 200.0f, 0.00999999978f, 0);

    DirectX::XMMATRIX Transform = DirectX::XMMatrixMultiply(identity, identity);
    Transform = XMMatrixMultiply(Transform, identity);
}

/*void Test2() {
    g_TestStruct.mousepos1 = DirectX::XMVector3Unproject(g_TestStruct.mousepos1, 0.0f, 0.0f, 1600.0f, 600.0f, 0.00999999978f, 1000.0f,
        g_TestStruct.identity, g_TestStruct.identity, g_TestStruct.identity);
}*/

void Test3() {
    DirectX::XMMATRIX identity = DirectX::XMMatrixIdentity();
    DirectX::XMVECTOR mousepos1 = DirectX::XMVectorSet(400.0f, 200.0f, 0.00999999978f, 0);

    mousepos1 = DirectX::XMVector3Unproject(mousepos1, 0.0f, 0.0f, 1600.0f, 600.0f, 0.00999999978f, 1000.0f,
        identity, identity, identity); // crash in inline XMMATRIX XM_CALLCONV XMMatrixMultiply at vX = _mm_mul_ps(vX,M2.r[0]); called by Transform = XMMatrixMultiply(Transform, Projection);
}

int main()
{
    Test1(); // works
    //Test2(); //crash

    Test3();  //crash

    return 0;

}

Edit: Just tested the newest version. Still crashes. Note: I forgot to set SSE2 in the attached repro. However setting it to SSE2 still crashes. Fast (/fp:fast) or Precise (/fp:precise) doesn't matter either. However using (/arch:AVX) does not crash, unfortunately not every customer of mine is able to use AVX. I don't know whether AVX does have different alignment requirements or there really is a bug. Of course x64 works like a charm.

Crash.zip

walbourn commented 6 years ago

Have you been able to repro this with an earlier Visual Studio? It looks like a compiler bug from your repro...

nasenbaer43 commented 6 years ago

Thanks for your reply. And nice idea... Changing the toolset to VS 2015 works. Starting to love all the new bugs in VS 2017 :(

Anyway thanks for your help.

walbourn commented 6 years ago

Alright, so please file this as a bug against the compiler at VS Connect.

My test suite passes fine on VS 2017 (15.3) Win32 Debug, but it obviously doesn't cover every possible usage. I realize this is mostly just a test, but what happens if you use XMVECTORF32 instead of XMVectorSet for the vector constants?

nasenbaer43 commented 6 years ago

Done. See https://developercommunity.visualstudio.com/content/problem/110426/c-compiler-bug-invalid-sse2-code-alignment.html in case I missed something.

Using XMVECTORF32 didn't help:

DirectX::XMMATRIX identity = DirectX::XMMatrixIdentity(); static const DirectX::XMVECTORF32 mousepos1 = { 400.0f, 200.0f, 0.00999999978f, 0.0f }; auto mouseposTest = DirectX::XMVector3Unproject(mousepos1, 0.0f, 0.0f, 1600.0f, 600.0f, 0.00999999978f, 1000.0f, identity, identity, identity);

still crashes

nasenbaer43 commented 6 years ago

Just had a look at your test suite: all the tests ran fine... However in your solution you set Program Database (/Zi) instead of Program Database for Edit And Continue (/ZI) which I'm using. Changing the setting removes the bug.

walbourn commented 6 years ago

Ah, definitely include that detail in the bug report.

walbourn commented 6 years ago

Note that the compiler team has seen this bug and repro'd it with 15.3. It didn't happen in the 15.2 compiler.

walbourn commented 6 years ago

Note that this still repros with 2017 (15.4)