diff --git a/include/xsimd/arch/xsimd_lasx.hpp b/include/xsimd/arch/xsimd_lasx.hpp index 55aa982b7..40415d014 100644 --- a/include/xsimd/arch/xsimd_lasx.hpp +++ b/include/xsimd/arch/xsimd_lasx.hpp @@ -1106,7 +1106,38 @@ namespace xsimd XSIMD_INLINE std::enable_if_t, batch> swizzle(batch const& self, batch_constant mask, requires_arch) noexcept { - return swizzle(self, mask.as_batch(), lasx {}); + if constexpr (detail::is_identity(mask)) + return self; + else if constexpr (sizeof(T) == 1) + { + constexpr auto lane_mask = mask % std::integral_constant(); + auto const self_int = detail::lasx_to_int(self); + + __m256i src; + if constexpr (!detail::is_cross_lane(mask)) + { + src = self_int; + } + else if constexpr (detail::is_only_from_lo(mask)) + { + src = __lasx_xvpermi_q(self_int, self_int, 0x00); + } + else if constexpr (detail::is_only_from_hi(mask)) + { + src = __lasx_xvpermi_q(self_int, self_int, 0x11); + } + else + { + return swizzle(self, mask.as_batch(), lasx {}); + } + + return detail::lasx_from_int( + __lasx_xvshuf_b(src, src, detail::lasx_to_int(lane_mask.as_batch()))); + } + else + { + return swizzle(self, mask.as_batch(), lasx {}); + } } } } diff --git a/include/xsimd/arch/xsimd_lsx.hpp b/include/xsimd/arch/xsimd_lsx.hpp index 598d01e9f..7f1ca30fe 100644 --- a/include/xsimd/arch/xsimd_lsx.hpp +++ b/include/xsimd/arch/xsimd_lsx.hpp @@ -999,7 +999,10 @@ namespace xsimd XSIMD_INLINE std::enable_if_t, batch> swizzle(batch const& self, batch_constant mask, requires_arch) noexcept { - return swizzle(self, mask.as_batch(), lsx {}); + if constexpr (detail::is_identity(mask)) + return self; + else + return swizzle(self, mask.as_batch(), lsx {}); } } }