This is an automated email from the ASF dual-hosted git repository.

apitrou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new dbbf7cf813 GH-49449: [C++] Backport xsimd neon fix (#49450)
dbbf7cf813 is described below

commit dbbf7cf8136da31b77f78f00a51d62992802c2c2
Author: Antoine Prouvost <[email protected]>
AuthorDate: Mon Mar 9 10:03:29 2026 +0100

    GH-49449: [C++] Backport xsimd neon fix (#49450)
    
    ### Rationale for this change
    Performance in hot code.
    There is a bug in xsimd where the rshift/lshift for Neon are implemented 
with a scalar loop instead of the appropriate SIMD intrinsics. This code path 
is core to the `unpack` routine in Parquet reads.
    https://github.com/xtensor-stack/xsimd/pull/1266
    
    ### What changes are included in this PR?
    A bug backport.
    
    ### Are these changes tested?
    Yes.
    
    ### Are there any user-facing changes?
    No.
    
    * GitHub Issue: #49449
    
    Authored-by: AntoinePrv <[email protected]>
    Signed-off-by: Antoine Pitrou <[email protected]>
---
 cpp/src/arrow/util/bpacking_simd_kernel_internal.h | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/cpp/src/arrow/util/bpacking_simd_kernel_internal.h 
b/cpp/src/arrow/util/bpacking_simd_kernel_internal.h
index f8cbe53292..70329dcb34 100644
--- a/cpp/src/arrow/util/bpacking_simd_kernel_internal.h
+++ b/cpp/src/arrow/util/bpacking_simd_kernel_internal.h
@@ -148,6 +148,10 @@ constexpr bool IsSse2 = std::is_base_of_v<xsimd::sse2, 
Arch>;
 template <typename Arch>
 constexpr bool IsAvx2 = std::is_base_of_v<xsimd::avx2, Arch>;
 
+/// Whether we are compiling for the Neon or above in the arm64 family.
+template <typename Arch>
+constexpr bool IsNeon = std::is_base_of_v<xsimd::neon, Arch>;
+
 /// Wrapper around ``xsimd::bitwise_lshift`` with optimizations for non 
implemented sizes.
 //
 // We replace the variable left shift by a variable multiply with a power of 
two.
@@ -196,6 +200,15 @@ auto left_shift(const xsimd::batch<Int, Arch>& batch,
     return xsimd::bitwise_cast<Int>(shifted0 | shifted1);
   }
 
+  // TODO(xsimd) bug fixed likely in xsimd>14.0.0
+  // https://github.com/xtensor-stack/xsimd/pull/1266
+  if constexpr (IsNeon<Arch>) {
+    using SInt = std::make_signed_t<Int>;
+    constexpr auto signed_shifts =
+        xsimd::batch_constant<SInt, Arch, static_cast<SInt>(kShifts)...>();
+    return xsimd::kernel::bitwise_lshift(batch, signed_shifts.as_batch(), 
Arch{});
+  }
+
   return batch << shifts;
 }
 
@@ -252,6 +265,15 @@ auto right_shift_by_excess(const xsimd::batch<Int, Arch>& 
batch,
     return xsimd::bitwise_rshift<kMaxRShift>(left_shift(batch, kLShifts));
   }
 
+  // TODO(xsimd) bug fixed likely in xsimd>14.0.0
+  // https://github.com/xtensor-stack/xsimd/pull/1266
+  if constexpr (IsNeon<Arch>) {
+    using SInt = std::make_signed_t<Int>;
+    constexpr auto signed_shifts =
+        xsimd::batch_constant<SInt, Arch, static_cast<SInt>(kShifts)...>();
+    return xsimd::kernel::bitwise_rshift(batch, signed_shifts.as_batch(), 
Arch{});
+  }
+
   return batch >> shifts;
 }
 

Reply via email to