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.54k stars 238 forks source link

Do not disable overloads for XMVECTOR for GNUC/clang when building with no-intrinsics #141

Closed misyltoad closed 2 years ago

misyltoad commented 2 years ago

In my experience, these work completely fine on a modern GCC.

This also adds a force macro to disable this functionality.

walbourn commented 2 years ago

I think the more robust test is actually __GXX_ABI_VERSION compare to 1004.

Try out:

#if !defined(_XM_NO_XMVECTOR_OVERLOADS_) && (defined(__clang__) || (defined(__GNUC__) && (__GXX_ABI_VERSION < 1004)))
walbourn commented 2 years ago

I'm trying GNUC 9.3.0 and I'm getting:

/home/walbourn/DirectXMath/Tests/../Inc/DirectXMath.h:477:33: error: ‘DirectX::XMVECTOR DirectX::operator+(DirectX::FXMVECTOR)’ must have an argument of class or enumerated type
477 |     XMVECTOR    XM_CALLCONV     operator+ (FXMVECTOR V) noexcept;

Which is the error that indicates it doesn't support overloading of __m128.

walbourn commented 2 years ago

So as far as I can tell, GCC doesn't support this for intrinsics types like __m128 which is what _XM_NO_XMVECTOR_OVERLOADS_ is there for. Same is true for clang.

Perhaps you were building with _XM_NO_INTRINSICS_ which defines it's own struct XMVECTOR which would work.

misyltoad commented 2 years ago

Ah yes, we define _XM_NO_INTRINSICS_. Perhaps when this is defined we can always enable the overloads?

walbourn commented 2 years ago

OK, that explains it.

Fixed in this commit.

denniskb commented 2 years ago

Sorry to revive this. I'm on GCC which disables overloads. I am not defining _XM_NO_INTRINSICS_. Yet, I can use operators. Expressions such as

min + scale * (XMVectorSet(x, y, z, 0) + 0.5)

work just fine (with min, scale being XMVECTORs). What's going on?

denniskb commented 2 years ago

LOL. It seems that's a GCC feature (or quirk). The following program compiles:

#include <pmmintrin.h>

int main() {
  __m128 x = _mm_set1_ps(1), y = _mm_set1_ps(2);
  auto z = x + y * 0.5;
  return 0;
}
walbourn commented 2 years ago

Have you looked at SimpleMath?