From e84b8d3f6f671faa0e072ca9a8bb4cdfdc6ca8db Mon Sep 17 00:00:00 2001 From: "A. Molzer" <5550310+197g@users.noreply.github.com> Date: Fri, 27 Feb 2026 07:40:50 +0100 Subject: [PATCH] [zerocopy] Re-enable big endian aarch64 types When initially released the LLVM semantics did not agree with the intrinsics in the order of lanes and hence they got removed from stable on big endian targets. The fix of these semantics was shipped with Rust 1.87 in March 2025 (). To keep the library working in these previous compiler versions the intrinsics are enabled by their prior condition, a little endian target is detected, or the feature detection cfg of the more recent rust release is present. Co-Authored-By: Jack Wrenn --- .github/workflows/ci.yml | 27 +++++++++++++++++++++++++++ Cargo.toml | 5 +++++ src/impls.rs | 22 ++++++++++++++++++---- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 59bae31e20..222bbb1bfe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -62,6 +62,7 @@ jobs: "no-zerocopy-generic-bounds-in-const-fn-1-61-0", "no-zerocopy-target-has-atomics-1-60-0", "no-zerocopy-aarch64-simd-1-59-0", + "no-zerocopy-aarch64-simd-be-1-87-0", "no-zerocopy-panic-in-const-and-vec-try-reserve-1-57-0" ] target: [ @@ -104,6 +105,8 @@ jobs: features: "--all-features" - toolchain: "no-zerocopy-aarch64-simd-1-59-0" features: "--all-features" + - toolchain: "no-zerocopy-aarch64-simd-be-1-87-0" + features: "--all-features" - toolchain: "no-zerocopy-panic-in-const-and-vec-try-reserve-1-57-0" features: "--all-features" # Exclude any combination for the zerocopy-derive crate which @@ -130,6 +133,8 @@ jobs: toolchain: "no-zerocopy-target-has-atomics-1-60-0" - crate: "zerocopy-derive" toolchain: "no-zerocopy-aarch64-simd-1-59-0" + - crate: "zerocopy-derive" + toolchain: "no-zerocopy-aarch64-simd-be-1-87-0" - crate: "zerocopy-derive" toolchain: "no-zerocopy-panic-in-const-and-vec-try-reserve-1-57-0" # Exclude stable/wasm since wasm is no longer provided via rustup on @@ -158,6 +163,28 @@ jobs: target: "thumbv6m-none-eabi" - toolchain: "no-zerocopy-aarch64-simd-1-59-0" target: "wasm32-unknown-unknown" + # Exclude non-aarch64 targets from the `no-zerocopy-aarch64-simd-be-1-87-0` + # toolchain. + - toolchain: "no-zerocopy-aarch64-simd-be-1-87-0" + target: "i686-unknown-linux-gnu" + - toolchain: "no-zerocopy-aarch64-simd-be-1-87-0" + target: "x86_64-unknown-linux-gnu" + - toolchain: "no-zerocopy-aarch64-simd-be-1-87-0" + target: "arm-unknown-linux-gnueabi" + - toolchain: "no-zerocopy-aarch64-simd-be-1-87-0" + target: "powerpc-unknown-linux-gnu" + - toolchain: "no-zerocopy-aarch64-simd-be-1-87-0" + target: "powerpc64-unknown-linux-gnu" + - toolchain: "no-zerocopy-aarch64-simd-be-1-87-0" + target: "riscv64gc-unknown-linux-gnu" + - toolchain: "no-zerocopy-aarch64-simd-be-1-87-0" + target: "s390x-unknown-linux-gnu" + - toolchain: "no-zerocopy-aarch64-simd-be-1-87-0" + target: "x86_64-pc-windows-msvc" + - toolchain: "no-zerocopy-aarch64-simd-be-1-87-0" + target: "thumbv6m-none-eabi" + - toolchain: "no-zerocopy-aarch64-simd-be-1-87-0" + target: "wasm32-unknown-unknown" # Exclude most targets from the `no-zerocopy-core-error-1-81-0` # toolchain since the `no-zerocopy-core-error-1-81-0` feature is unrelated to # compilation target. This only leaves i686 and x86_64 targets. diff --git a/Cargo.toml b/Cargo.toml index 56f4fa11b4..9fbaa31192 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -79,6 +79,11 @@ no-zerocopy-target-has-atomics-1-60-0 = "1.60.0" # versions, these types require the "simd-nightly" feature. no-zerocopy-aarch64-simd-1-59-0 = "1.59.0" +# Include SIMD types from `core::arch::aarch64` on big endian targets. Prior to +# 1.87.0 (https://github.com/rust-lang/rust/pull/136831) the types were only +# correct on little endian and backed off from stable in a breaking change. +no-zerocopy-aarch64-simd-be-1-87-0 = "1.87.0" + # Permit panicking in `const fn`s and calling `Vec::try_reserve`. no-zerocopy-panic-in-const-and-vec-try-reserve-1-57-0 = "1.57.0" diff --git a/src/impls.rs b/src/impls.rs index 02153b86c4..80538bfc8a 100644 --- a/src/impls.rs +++ b/src/impls.rs @@ -1350,12 +1350,26 @@ mod simd { #[cfg(all(feature = "simd-nightly", target_arch = "powerpc64"))] powerpc64, powerpc64, vector_bool_long, vector_double, vector_signed_long, vector_unsigned_long ); + // NOTE: NEON intrinsics were broken on big-endian platforms from their stabilization up to + // Rust 1.87. (Context in https://github.com/rust-lang/stdarch/issues/1484). Support is + // split in two different version ranges on top of the base configuration, requiring either + // little endian or the more recent version to be detected as well. #[cfg(not(no_zerocopy_aarch64_simd_1_59_0))] simd_arch_mod!( - // NOTE(https://github.com/rust-lang/stdarch/issues/1484): NEON intrinsics are currently - // broken on big-endian platforms. - #[cfg(all(target_arch = "aarch64", target_endian = "little"))] - #[cfg_attr(doc_cfg, doc(cfg(rust = "1.59.0")))] + #[cfg(all( + target_arch = "aarch64", + any( + target_endian = "little", + not(no_zerocopy_aarch64_simd_be_1_87_0) + ) + ))] + #[cfg_attr( + doc_cfg, + doc(cfg(all(target_arch = "aarch64", any( + all(rust = "1.59.0", target_endian = "little"), + rust = "1.87.0", + )))) + )] aarch64, aarch64, float32x2_t, float32x4_t, float64x1_t, float64x2_t, int8x8_t, int8x8x2_t, int8x8x3_t, int8x8x4_t, int8x16_t, int8x16x2_t, int8x16x3_t, int8x16x4_t, int16x4_t, int16x8_t, int32x2_t, int32x4_t, int64x1_t, int64x2_t, poly8x8_t, poly8x8x2_t, poly8x8x3_t,