Skip to content

Commit 6c2fb49

Browse files
committed
Work around slow _mm_packus_epi16 in Rust 1.96 through 1.98, inclusive
See rust-lang/stdarch#2208
1 parent 9451175 commit 6c2fb49

4 files changed

Lines changed: 53 additions & 1 deletion

File tree

Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ version = "0.8.35"
55
edition = '2024'
66
authors = ["Henri Sivonen <hsivonen@hsivonen.fi>"]
77
license = "(Apache-2.0 OR MIT) AND BSD-3-Clause"
8-
include = ["src/**/*.rs", "/data", "Cargo.toml", "COPYRIGHT", "LICENSE*", "README.md"]
8+
include = ["build.rs", "src/**/*.rs", "/data", "Cargo.toml", "COPYRIGHT", "LICENSE*", "README.md"]
99
readme = "README.md"
1010
documentation = "https://docs.rs/encoding_rs/"
1111
homepage = "https://docs.rs/encoding_rs/"
1212
repository = "https://github.com/hsivonen/encoding_rs"
1313
keywords = ["encoding", "web", "unicode", "charset"]
1414
categories = ["text-processing", "encoding", "web-programming", "internationalization"]
1515
rust-version = "1.88"
16+
build = "build.rs"
1617

1718
[features]
1819
default = ["alloc"]
@@ -58,6 +59,9 @@ serde_derive = "1.0"
5859
bincode = "1.0"
5960
serde_json = "1.0"
6061

62+
[build-dependencies]
63+
rustversion = "1.0.19"
64+
6165
[profile.release]
6266
lto = true
6367

build.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fn main() {
2+
println!("cargo::rustc-check-cfg=cfg(slow_mm_packus_epi16)");
3+
if rustversion::cfg!(all(since(1.96), before(1.99))) {
4+
println!("cargo:rustc-cfg=slow_mm_packus_epi16");
5+
}
6+
}

src/lib.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,22 @@
728728
all(feature = "simd-accel", target_endian = "little"),
729729
feature(portable_simd)
730730
)]
731+
// These are for working around
732+
// https://github.com/rust-lang/stdarch/issues/2208
733+
// https://github.com/rust-lang/rust/issues/159464
734+
// https://github.com/rust-lang/rust/pull/161558
735+
#![cfg_attr(
736+
all(slow_mm_packus_epi16, feature = "simd-accel", target_feature = "sse2"),
737+
feature(link_llvm_intrinsics)
738+
)]
739+
#![cfg_attr(
740+
all(slow_mm_packus_epi16, feature = "simd-accel", target_feature = "sse2"),
741+
feature(abi_unadjusted)
742+
)]
743+
#![cfg_attr(
744+
all(slow_mm_packus_epi16, feature = "simd-accel", target_feature = "sse2"),
745+
feature(simd_ffi)
746+
)]
731747

732748
#[cfg(feature = "alloc")]
733749
#[cfg_attr(test, macro_use)]

src/simd_funcs.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,43 @@ cfg_if! {
5454
#[allow(unused)]
5555
use core::arch::x86_64::__m128i;
5656
use core::arch::x86_64::_mm_movemask_epi8;
57+
#[rustversion::any(before(1.96), since(1.99))]
5758
use core::arch::x86_64::_mm_packus_epi16;
5859
} else if #[cfg(all(target_feature = "sse2", target_arch = "x86"))] {
5960
#[allow(unused)]
6061
use core::arch::x86::__m128i;
6162
use core::arch::x86::_mm_movemask_epi8;
63+
#[rustversion::any(before(1.96), since(1.99))]
6264
use core::arch::x86::_mm_packus_epi16;
6365
} else {
6466

6567
}
6668
}
6769

70+
cfg_if! {
71+
if #[cfg(target_feature = "sse2")] {
72+
// See:
73+
//
74+
// https://github.com/rust-lang/stdarch/issues/2208
75+
// https://github.com/rust-lang/rust/issues/159464
76+
// https://github.com/rust-lang/rust/pull/161558
77+
#[rustversion::all(since(1.96), before(1.99))]
78+
unsafe fn _mm_packus_epi16(a: __m128i, b: __m128i) -> __m128i {
79+
unsafe { packus(core::simd::i16x8::from(a), core::simd::i16x8::from(b)).into() }
80+
}
81+
82+
#[rustversion::all(since(1.96), before(1.99))]
83+
#[allow(improper_ctypes)]
84+
unsafe extern "unadjusted" {
85+
#[link_name = "llvm.x86.sse2.packuswb.128"]
86+
fn packus(a: core::simd::i16x8, b: core::simd::i16x8) -> u8x16;
87+
}
88+
89+
} else {
90+
91+
}
92+
}
93+
6894
// #[inline(always)]
6995
// fn simd_byte_swap_u8(s: u8x16) -> u8x16 {
7096
// unsafe {

0 commit comments

Comments
 (0)