Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions common/simd/vboolf4_sse2.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,17 @@ namespace embree
typedef vfloat4 Float;

enum { size = 4 }; // number of SIMD elements
// The __m128_wrapper indirection is only required to work around an
// MSVC/ARM64 overload-ambiguity issue (__m128 and __m128i both alias
// __n128 there). On all other platforms we keep the plain __m128 union
// member, which is what x86 and non-MSVC ARM64 builds have always used
// (see simd_wrapper_types.h); wrapping it unconditionally previously
// caused miscompiles/segfaults with some optimizing compilers (e.g. ICX).
#if defined(_MSC_VER) && defined(_M_ARM64)
union { __m128_wrapper v; int i[4]; }; // data
#else
union { __m128 v; int i[4]; }; // data
#endif

////////////////////////////////////////////////////////////////////////////////
/// Constructors, Assignment & Cast Operators
Expand All @@ -37,11 +47,22 @@ namespace embree
__forceinline vboolf4& operator =(const vboolf4& other) { v = other.v; return *this; }

__forceinline vboolf(__m128 input) : v(input) {}
#if defined(_MSC_VER) && defined(_M_ARM64)
__forceinline operator const __m128&() const { return v.data; }
#if !defined(__EMSCRIPTEN__)
__forceinline const __m128i m128i() const { return _mm_castps_si128(v.data); }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One could just remove the .data here and the functions should also work without the wrapper, the wrapper has conversion operators to the base type

__forceinline const __m128d m128d() const { return _mm_castps_pd(v.data); }
#endif
#else
__forceinline operator const __m128&() const { return v; }
#if !defined(__EMSCRIPTEN__)
__forceinline operator const __m128i() const { return _mm_castps_si128(v); }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we add this operator only in that case? We should now only go through new functions.

__forceinline operator const __m128d() const { return _mm_castps_pd(v); }
/* kept for source compatibility with code that calls .m128i()/.m128d() explicitly */
__forceinline const __m128i m128i() const { return _mm_castps_si128(v); }
__forceinline const __m128d m128d() const { return _mm_castps_pd(v); }
#endif
#endif

__forceinline vboolf(bool a)
: v(mm_lookupmask_ps[(size_t(a) << 3) | (size_t(a) << 2) | (size_t(a) << 1) | size_t(a)]) {}
Expand Down
10 changes: 10 additions & 0 deletions common/simd/vfloat4_sse2.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ namespace embree
typedef vfloat4 Float;

enum { size = 4 }; // number of SIMD elements
// See vboolf4_sse2.h for why the wrapper is restricted to MSVC/ARM64.
#if defined(_MSC_VER) && defined(_M_ARM64)
union { __m128_wrapper v; float f[4]; int i[4]; }; // data
#else
union { __m128 v; float f[4]; int i[4]; }; // data
#endif

////////////////////////////////////////////////////////////////////////////////
/// Constructors, Assignment & Cast Operators
Expand All @@ -39,8 +44,13 @@ namespace embree
__forceinline vfloat4& operator =(const vfloat4& other) { v = other.v; return *this; }

__forceinline vfloat(__m128 a) : v(a) {}
#if defined(_MSC_VER) && defined(_M_ARM64)
__forceinline operator const __m128&() const { return v.data; }
__forceinline operator __m128&() { return v.data; }
#else
__forceinline operator const __m128&() const { return v; }
__forceinline operator __m128&() { return v; }
#endif

__forceinline vfloat(float a) : v(_mm_set1_ps(a)) {}
__forceinline vfloat(float a, float b, float c, float d) : v(_mm_set_ps(d, c, b, a)) {}
Expand Down
10 changes: 10 additions & 0 deletions common/simd/vint4_sse2.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ namespace embree
typedef vfloat4 Float;

enum { size = 4 }; // number of SIMD elements
// See vboolf4_sse2.h for why the wrapper is restricted to MSVC/ARM64.
#if defined(_MSC_VER) && defined(_M_ARM64)
union { __m128i_wrapper v; int i[4]; }; // data
#else
union { __m128i v; int i[4]; }; // data
#endif

////////////////////////////////////////////////////////////////////////////////
/// Constructors, Assignment & Cast Operators
Expand All @@ -38,8 +43,13 @@ namespace embree
__forceinline vint4& operator =(const vint4& a) { v = a.v; return *this; }

__forceinline vint(__m128i a) : v(a) {}
#if defined(_MSC_VER) && defined(_M_ARM64)
__forceinline operator const __m128i&() const { return v.data; }
__forceinline operator __m128i&() { return v.data; }
#else
__forceinline operator const __m128i&() const { return v; }
__forceinline operator __m128i&() { return v; }
#endif

__forceinline vint(int a) : v(_mm_set1_epi32(a)) {}
__forceinline vint(int a, int b, int c, int d) : v(_mm_set_epi32(d, c, b, a)) {}
Expand Down
10 changes: 10 additions & 0 deletions common/simd/vuint4_sse2.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ namespace embree
typedef vfloat4 Float;

enum { size = 4 }; // number of SIMD elements
// See vboolf4_sse2.h for why the wrapper is restricted to MSVC/ARM64.
#if defined(_MSC_VER) && defined(_M_ARM64)
union { __m128i_wrapper v; unsigned int i[4]; }; // data
#else
union { __m128i v; unsigned int i[4]; }; // data
#endif

////////////////////////////////////////////////////////////////////////////////
/// Constructors, Assignment & Cast Operators
Expand All @@ -38,8 +43,13 @@ namespace embree
__forceinline vuint4& operator =(const vuint4& a) { v = a.v; return *this; }

__forceinline vuint(const __m128i a) : v(a) {}
#if defined(_MSC_VER) && defined(_M_ARM64)
__forceinline operator const __m128i&() const { return v.data; }
__forceinline operator __m128i&() { return v.data; }
#else
__forceinline operator const __m128i&() const { return v; }
__forceinline operator __m128i&() { return v; }
#endif


__forceinline vuint(unsigned int a) : v(_mm_set1_epi32(a)) {}
Expand Down
Loading