14

Compiling with VS2012 and working with the DirectXMath library, I encountered an issue where it appeared that the compiler wasn't aligning my XMMATRIX. I simplified the issue down to the following.

#include <DirectXMath.h>
using namespace DirectX;

int _tmain(int argc, _TCHAR* argv[])
{
  auto m1 = XMMatrixIdentity();
  auto m2 = XMMatrixIdentity();

  auto t1 = XMMatrixTranspose( m1 ); // sometimes access violation occurs here
  auto t2 = XMMatrixTranspose( m2 ); // or sometimes here

  return 0;
}

Re-running the code over and over will sometimes cause an "Access violation reading location 0xFFFFFFFF" on the first transpose, sometimes on the second.

I've figured out this is due to the fact that m1 and m2 are not being properly aligned. Replacing "auto" with "XMMATRIX" seems to solve the issue, so my suspicion is a compiler bug, but its also possible that I'm doing something wrong, or not enabling some option.

Is there something wrong with my code or is this a compiler bug?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
MerickOWA
  • 7,453
  • 1
  • 35
  • 56
  • Did you have a look at the resulting assembly to check for any differences ? – J.N. Sep 04 '12 at 00:18
  • @J.N. yes, if I don't use "auto" then it definitely has extra instructions which fiddle with esp and (I assume) helps ensure that the two XMMATRIXs are aligned properly. – MerickOWA Sep 04 '12 at 01:29
  • Well, unless `XMMATRIX` is a macro I vote for a compiler bug. If it is a macro then it may be a DX bug... – J.N. Sep 04 '12 at 02:15
  • what does `__alignof` return for your auto'd types? its possible that you require at least one non automatic definition to trigger stack alignment(which is a compiler bug). – Necrolis Sep 04 '12 at 06:52
  • @J.N. : It's a struct containing a `XMVECTOR[4]`. That in turn is a platform-dependent type (e.g. an SSE type on x86). – MSalters Sep 04 '12 at 07:04
  • 2
    As a workaround, use `__declspec(align(16))`. Sure, this is a Microsoft-specific extension, but it's also a Microsoft-specific bug. – MSalters Sep 04 '12 at 07:09
  • I've opened a microsoft connect issue here for those who want to follow the issue. https://connect.microsoft.com/VisualStudio/feedback/details/761026/xmmatrix-not-properly-aligned-when-using-c-11-auto-keyword – MerickOWA Sep 12 '12 at 21:56
  • This has been fixed now in VS2013 – MerickOWA Nov 02 '13 at 16:20

3 Answers3

3

The definition for XMMATRIX has the following in the header file (xnamath.h), although this could be different in your version.

// Matrix type: Sixteen 32 bit floating point components aligned on a
// 16 byte boundary and mapped to four hardware vector registers
#if (defined(_XM_X86_) || defined(_XM_X64_)) && defined(_XM_NO_INTRINSICS_)
typedef struct _XMMATRIX
#else
typedef _DECLSPEC_ALIGN_16_ struct _XMMATRIX
#endif

So XMMATRIX is defined with __declspec(align(16)) (if you look through the header files it does reduce to this), which is a Microsoft specific extension. It's not a macro. This means it's a compiler bug, the compiler is failing to propagate these proprietary attributes to variables defined with the auto keyword.

It's probably best to just avoid the use of the auto keyword in this case, it's probably neater than explicitly adding the declspec yourself.

jleahy
  • 16,149
  • 6
  • 47
  • 66
2

This is definitely a compiler bug. I can reproduce it too with my own math classes. I've opened a ticket here so vote for it. You can avoid using the auto keyword, as was mentioned. Or you can compile to x64 where the bug is not present (or at least i was unable to reproduce it; my not-so-simple program works perfectly).

Roman Zavalov
  • 575
  • 3
  • 8
  • It was already added to Microsoft connect. Microsoft says will be fixed in the next release of C++ https://connect.microsoft.com/VisualStudio/feedback/details/761026/xmmatrix-not-properly-aligned-when-using-c-11-auto-keyword – MerickOWA Dec 29 '12 at 21:55
  • Looks like it still not fixed at VS2012. – Trax Apr 27 '13 at 17:18
  • @Trax This has been fixed now in VS2013 – MerickOWA Nov 02 '13 at 16:19
0

For Visual Studio 2012, I was able to implement a "work-around" it by splitting the statement in two lines:

XMMATRIX mtxMyWorldTrnspd = mtxMyWorld;
mtxMyWorldTrnspd = XMMatrixTranspose(mtxMyWorldTrnspd);