Skip to content

Commit f9d7240

Browse files
AntoinePrvclaude
andcommitted
Fix xsimd_neon64.hpp for MSVC ARM64
Two issues newly exposed after fixing xsimd_neon.hpp: 1. reducer_return_type_impl used explicit template specializations. On MSVC ARM64 all NEON vector types share the same underlying __n128 type, so all specializations clashed (C2766: already defined). Replace with a primary template using std::conditional chains, following the same pattern as comp_return_type_impl in xsimd_neon.hpp. 2. WRAP_CAST used ::vreinterpretq_f64_* calls. On MSVC ARM64, vreinterpretq_* are macros that expand to cast expressions starting with '(', so ::macro(x) becomes ::(cast)... which MSVC rejects (C2589: illegal token after ::). Drop :: from those calls. Note: WRAP_REDUCER wrappers keep :: because the wrapper function has the same name as the intrinsic (no x_ prefix), making :: necessary to avoid recursion. Reducer intrinsics are actual functions on MSVC ARM64 (not macros), so :: works correctly there. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent a7d7909 commit f9d7240

1 file changed

Lines changed: 36 additions & 62 deletions

File tree

include/xsimd/arch/xsimd_neon64.hpp

Lines changed: 36 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -947,67 +947,41 @@ namespace xsimd
947947

948948
namespace detail
949949
{
950-
template <class R>
951-
struct reducer_return_type_impl;
952-
953-
template <>
954-
struct reducer_return_type_impl<uint8x16_t>
955-
{
956-
using type = uint8_t;
957-
};
958-
959-
template <>
960-
struct reducer_return_type_impl<int8x16_t>
961-
{
962-
using type = int8_t;
963-
};
964-
965-
template <>
966-
struct reducer_return_type_impl<uint16x8_t>
967-
{
968-
using type = uint16_t;
969-
};
970-
971-
template <>
972-
struct reducer_return_type_impl<int16x8_t>
973-
{
974-
using type = int16_t;
975-
};
976-
977-
template <>
978-
struct reducer_return_type_impl<uint32x4_t>
979-
{
980-
using type = uint32_t;
981-
};
982-
983-
template <>
984-
struct reducer_return_type_impl<int32x4_t>
985-
{
986-
using type = int32_t;
987-
};
988-
989-
template <>
990-
struct reducer_return_type_impl<uint64x2_t>
991-
{
992-
using type = uint64_t;
993-
};
994-
995-
template <>
996-
struct reducer_return_type_impl<int64x2_t>
997-
{
998-
using type = int64_t;
999-
};
1000-
1001-
template <>
1002-
struct reducer_return_type_impl<float32x4_t>
1003-
{
1004-
using type = float;
1005-
};
1006-
1007-
template <>
1008-
struct reducer_return_type_impl<float64x2_t>
950+
// On MSVC ARM64, all NEON vector types share the same underlying __n128 type,
951+
// making explicit template specialization impossible (C2766). Use a primary
952+
// template with std::conditional chains instead, matching the pattern used
953+
// for comp_return_type_impl in xsimd_neon.hpp.
954+
template <class T>
955+
struct reducer_return_type_impl
1009956
{
1010-
using type = double;
957+
using type = typename std::conditional<
958+
std::is_same<T, uint8x16_t>::value,
959+
uint8_t,
960+
typename std::conditional<
961+
std::is_same<T, int8x16_t>::value,
962+
int8_t,
963+
typename std::conditional<
964+
std::is_same<T, uint16x8_t>::value,
965+
uint16_t,
966+
typename std::conditional<
967+
std::is_same<T, int16x8_t>::value,
968+
int16_t,
969+
typename std::conditional<
970+
std::is_same<T, uint32x4_t>::value,
971+
uint32_t,
972+
typename std::conditional<
973+
std::is_same<T, int32x4_t>::value,
974+
int32_t,
975+
typename std::conditional<
976+
std::is_same<T, uint64x2_t>::value,
977+
uint64_t,
978+
typename std::conditional<
979+
std::is_same<T, int64x2_t>::value,
980+
int64_t,
981+
typename std::conditional<
982+
std::is_same<T, float32x4_t>::value,
983+
float,
984+
double>::type>::type>::type>::type>::type>::type>::type>::type>::type;
1011985
};
1012986

1013987
template <class R>
@@ -1359,11 +1333,11 @@ namespace xsimd
13591333
{ \
13601334
XSIMD_INLINE float64x2_t(x_vreinterpretq_f64_##SUFFIX)(TYPE a) noexcept \
13611335
{ \
1362-
return ::vreinterpretq_f64_##SUFFIX(a); \
1336+
return vreinterpretq_f64_##SUFFIX(a); \
13631337
} \
13641338
XSIMD_INLINE TYPE(x_vreinterpretq_##SUFFIX##_f64)(float64x2_t a) noexcept \
13651339
{ \
1366-
return ::vreinterpretq_##SUFFIX##_f64(a); \
1340+
return vreinterpretq_##SUFFIX##_f64(a); \
13671341
} \
13681342
}
13691343

0 commit comments

Comments
 (0)