Skip to content
Merged
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
4 changes: 3 additions & 1 deletion include/xsimd/arch/xsimd_neon.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3308,7 +3308,9 @@ namespace xsimd
requires_arch<neon>) noexcept
{
static_assert(batch<T, A>::size == sizeof...(idx), "valid swizzle indices");
std::array<T, batch<T, A>::size> data;
// std::array is only aligned to alignof(T), while store_aligned requires
// the full batch alignment
alignas(A::alignment()) std::array<T, batch<T, A>::size> data;
self.store_aligned(data.data());
return set(batch<T, A>(), A(), data[idx]...);
}
Expand Down
38 changes: 38 additions & 0 deletions test/test_batch_manip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,44 @@ TEST_CASE_TEMPLATE("[swizzle]", B, BATCH_SWIZZLE_TYPES)
SUBCASE("rotate_right") { swizzle_test<B>().rotate_right(); }
}

// Regression test for https://github.com/xtensor-stack/xsimd/issues/1260: the generic
// swizzle kernel stored to an std::array aligned only to alignof(T), tripping the
// alignment assertion in store_aligned for the 8- and 16-bit batches that use it.
// Run on every supported architecture, not just the default one, so the generic
// kernels of the narrower archs are exercised too
struct check_narrow_swizzle_and_reduce
{
template <class Arch>
void operator()(Arch) const
{
if (!Arch::available())
{
return;
}
check_for<uint8_t, Arch>();
check_for<int8_t, Arch>();
check_for<uint16_t, Arch>();
check_for<int16_t, Arch>();
}

template <class T, class Arch>
void check_for() const
{
using B = xsimd::batch<T, Arch>;
swizzle_test<B>().template run<xsimd::Reversor>();
swizzle_test<B>().template run<xsimd::EvenThenOdd>();
swizzle_test<B>().template run<xsimd::RotateRight1>();
auto lhs = swizzle_test<B>::make_lhs();
auto b = B::load_unaligned(lhs.data());
CHECK_EQ(xsimd::reduce_max(b), lhs[B::size - 1]);
}
};

TEST_CASE("[narrow swizzle and reduce_max on every supported architecture]")
{
xsimd::supported_architectures::for_each(check_narrow_swizzle_and_reduce {});
}

#undef XSIMD_SWIZZLE_PATTERN_CASE

#endif /* XSIMD_NO_SUPPORTED_ARCHITECTURE */
Loading