Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b24a2f2
Initial pass at swizzle_dyn, ported from std::simd
Shnatsel Jul 19, 2026
54d6760
Add a 256-bit SSE4.2 implementation as an experiment
Shnatsel Jul 19, 2026
29262e1
Split out recursive swizzle formulation into a helper and apply it to…
Shnatsel Jul 19, 2026
51113e8
Implement a dedicated AVX2 512-bit shuffle path
Shnatsel Jul 19, 2026
e037904
Apply the or trick to the dedicated AVX2 512-bit implementation to se…
Shnatsel Jul 19, 2026
6fd5d86
Revert "Apply the or trick to the dedicated AVX2 512-bit implementati…
Shnatsel Jul 19, 2026
c79bf96
More detailed comment on the AVX2-optimized shuffle
Shnatsel Jul 19, 2026
e1e605d
Reuse the recursive decomposition for WASM 256-bit case
Shnatsel Jul 19, 2026
1ff3d16
Add random testing for swizzle_dyn_precise correctness, since it's pr…
Shnatsel Jul 19, 2026
1d95366
Revert "Add random testing for swizzle_dyn_precise correctness, since…
Shnatsel Jul 19, 2026
e0a3225
Use an unwrap instead of a cast to appease clippy
Shnatsel Jul 19, 2026
710825b
Fix typo
Shnatsel Jul 19, 2026
79de6c0
Remove 512-bit shuffle specialized for AVX2 and route through the gen…
Shnatsel Jul 19, 2026
8aee113
Implement a custom AVX2 shuffle instead of reusing the std::simd one.…
Shnatsel Jul 20, 2026
ab3fd43
Empty commit to re-run stuck CI
Shnatsel Jul 23, 2026
19a1ed9
Merge branch 'main' into swizzle-dyn-precise
Shnatsel Jul 24, 2026
3e3a00c
Optimize SSE4.2 as suggested by axnsan12. Changes the control sequenc…
Shnatsel Jul 25, 2026
2607a59
Merge main with conflicts preserved for audit
Shnatsel Jul 28, 2026
2d4449f
Resolve main merge conflicts
Shnatsel Jul 28, 2026
8295362
Merge branch 'main' into swizzle-dyn-precise
Shnatsel Jul 28, 2026
896f209
Reintroduce swizzle_dyn_precise random test behind #[ignore]
Shnatsel Jul 28, 2026
2708918
placate clippy
Shnatsel Jul 28, 2026
af454fe
Use a faster formulation of swizzle_dyn_precise on AVX-512 VBMI.
Shnatsel Jul 30, 2026
b5832c6
Use a better formulation for fallback swizzle_dyn_precise that lowers…
Shnatsel Aug 4, 2026
dc70e3f
Placate clippy
Shnatsel Aug 4, 2026
685d429
Simplify the fallback formulation for swizzle_dyn_precise
Shnatsel Aug 4, 2026
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
680 changes: 680 additions & 0 deletions fearless_simd/src/generated/avx2.rs

Large diffs are not rendered by default.

540 changes: 540 additions & 0 deletions fearless_simd/src/generated/avx512.rs

Large diffs are not rendered by default.

360 changes: 360 additions & 0 deletions fearless_simd/src/generated/fallback.rs

Large diffs are not rendered by default.

520 changes: 520 additions & 0 deletions fearless_simd/src/generated/neon.rs

Large diffs are not rendered by default.

62 changes: 62 additions & 0 deletions fearless_simd/src/generated/simd_trait.rs

Large diffs are not rendered by default.

150 changes: 150 additions & 0 deletions fearless_simd/src/generated/simd_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ impl<S: Simd> SimdBase<S> for f32x4<S> {
self.simd
.swizzle_dyn_within_blocks_f32x4(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_f32x4(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdFloat<S> for f32x4<S> {
#[inline(always)]
Expand Down Expand Up @@ -458,6 +463,11 @@ impl<S: Simd> SimdBase<S> for i8x16<S> {
self.simd
.swizzle_dyn_within_blocks_i8x16(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_i8x16(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for i8x16<S> {
#[inline(always)]
Expand Down Expand Up @@ -689,6 +699,11 @@ impl<S: Simd> SimdBase<S> for u8x16<S> {
self.simd
.swizzle_dyn_within_blocks_u8x16(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_u8x16(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for u8x16<S> {
#[inline(always)]
Expand Down Expand Up @@ -1003,6 +1018,11 @@ impl<S: Simd> SimdBase<S> for i16x8<S> {
self.simd
.swizzle_dyn_within_blocks_i16x8(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_i16x8(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for i16x8<S> {
#[inline(always)]
Expand Down Expand Up @@ -1226,6 +1246,11 @@ impl<S: Simd> SimdBase<S> for u16x8<S> {
self.simd
.swizzle_dyn_within_blocks_u16x8(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_u16x8(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for u16x8<S> {
#[inline(always)]
Expand Down Expand Up @@ -1531,6 +1556,11 @@ impl<S: Simd> SimdBase<S> for i32x4<S> {
self.simd
.swizzle_dyn_within_blocks_i32x4(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_i32x4(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for i32x4<S> {
#[inline(always)]
Expand Down Expand Up @@ -1757,6 +1787,11 @@ impl<S: Simd> SimdBase<S> for u32x4<S> {
self.simd
.swizzle_dyn_within_blocks_u32x4(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_u32x4(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for u32x4<S> {
#[inline(always)]
Expand Down Expand Up @@ -2074,6 +2109,11 @@ impl<S: Simd> SimdBase<S> for f64x2<S> {
self.simd
.swizzle_dyn_within_blocks_f64x2(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_f64x2(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdFloat<S> for f64x2<S> {
#[inline(always)]
Expand Down Expand Up @@ -2342,6 +2382,11 @@ impl<S: Simd> SimdBase<S> for i64x2<S> {
self.simd
.swizzle_dyn_within_blocks_i64x2(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_i64x2(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for i64x2<S> {
#[inline(always)]
Expand Down Expand Up @@ -2556,6 +2601,11 @@ impl<S: Simd> SimdBase<S> for u64x2<S> {
self.simd
.swizzle_dyn_within_blocks_u64x2(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_u64x2(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for u64x2<S> {
#[inline(always)]
Expand Down Expand Up @@ -2870,6 +2920,11 @@ impl<S: Simd> SimdBase<S> for f32x8<S> {
self.simd
.swizzle_dyn_within_blocks_f32x8(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_f32x8(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdFloat<S> for f32x8<S> {
#[inline(always)]
Expand Down Expand Up @@ -3192,6 +3247,11 @@ impl<S: Simd> SimdBase<S> for i8x32<S> {
self.simd
.swizzle_dyn_within_blocks_i8x32(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_i8x32(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for i8x32<S> {
#[inline(always)]
Expand Down Expand Up @@ -3446,6 +3506,11 @@ impl<S: Simd> SimdBase<S> for u8x32<S> {
self.simd
.swizzle_dyn_within_blocks_u8x32(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_u8x32(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for u8x32<S> {
#[inline(always)]
Expand Down Expand Up @@ -3781,6 +3846,11 @@ impl<S: Simd> SimdBase<S> for i16x16<S> {
self.simd
.swizzle_dyn_within_blocks_i16x16(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_i16x16(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for i16x16<S> {
#[inline(always)]
Expand Down Expand Up @@ -4026,6 +4096,11 @@ impl<S: Simd> SimdBase<S> for u16x16<S> {
self.simd
.swizzle_dyn_within_blocks_u16x16(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_u16x16(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for u16x16<S> {
#[inline(always)]
Expand Down Expand Up @@ -4348,6 +4423,11 @@ impl<S: Simd> SimdBase<S> for i32x8<S> {
self.simd
.swizzle_dyn_within_blocks_i32x8(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_i32x8(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for i32x8<S> {
#[inline(always)]
Expand Down Expand Up @@ -4590,6 +4670,11 @@ impl<S: Simd> SimdBase<S> for u32x8<S> {
self.simd
.swizzle_dyn_within_blocks_u32x8(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_u32x8(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for u32x8<S> {
#[inline(always)]
Expand Down Expand Up @@ -4914,6 +4999,11 @@ impl<S: Simd> SimdBase<S> for f64x4<S> {
self.simd
.swizzle_dyn_within_blocks_f64x4(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_f64x4(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdFloat<S> for f64x4<S> {
#[inline(always)]
Expand Down Expand Up @@ -5189,6 +5279,11 @@ impl<S: Simd> SimdBase<S> for i64x4<S> {
self.simd
.swizzle_dyn_within_blocks_i64x4(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_i64x4(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for i64x4<S> {
#[inline(always)]
Expand Down Expand Up @@ -5410,6 +5505,11 @@ impl<S: Simd> SimdBase<S> for u64x4<S> {
self.simd
.swizzle_dyn_within_blocks_u64x4(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_u64x4(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for u64x4<S> {
#[inline(always)]
Expand Down Expand Up @@ -5746,6 +5846,11 @@ impl<S: Simd> SimdBase<S> for f32x16<S> {
self.simd
.swizzle_dyn_within_blocks_f32x16(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_f32x16(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdFloat<S> for f32x16<S> {
#[inline(always)]
Expand Down Expand Up @@ -6095,6 +6200,11 @@ impl<S: Simd> SimdBase<S> for i8x64<S> {
self.simd
.swizzle_dyn_within_blocks_i8x64(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_i8x64(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for i8x64<S> {
#[inline(always)]
Expand Down Expand Up @@ -6375,6 +6485,11 @@ impl<S: Simd> SimdBase<S> for u8x64<S> {
self.simd
.swizzle_dyn_within_blocks_u8x64(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_u8x64(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for u8x64<S> {
#[inline(always)]
Expand Down Expand Up @@ -6720,6 +6835,11 @@ impl<S: Simd> SimdBase<S> for i16x32<S> {
self.simd
.swizzle_dyn_within_blocks_i16x32(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_i16x32(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for i16x32<S> {
#[inline(always)]
Expand Down Expand Up @@ -6975,6 +7095,11 @@ impl<S: Simd> SimdBase<S> for u16x32<S> {
self.simd
.swizzle_dyn_within_blocks_u16x32(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_u16x32(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for u16x32<S> {
#[inline(always)]
Expand Down Expand Up @@ -7305,6 +7430,11 @@ impl<S: Simd> SimdBase<S> for i32x16<S> {
self.simd
.swizzle_dyn_within_blocks_i32x16(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_i32x16(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for i32x16<S> {
#[inline(always)]
Expand Down Expand Up @@ -7556,6 +7686,11 @@ impl<S: Simd> SimdBase<S> for u32x16<S> {
self.simd
.swizzle_dyn_within_blocks_u32x16(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_u32x16(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for u32x16<S> {
#[inline(always)]
Expand Down Expand Up @@ -7884,6 +8019,11 @@ impl<S: Simd> SimdBase<S> for f64x8<S> {
self.simd
.swizzle_dyn_within_blocks_f64x8(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_f64x8(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdFloat<S> for f64x8<S> {
#[inline(always)]
Expand Down Expand Up @@ -8162,6 +8302,11 @@ impl<S: Simd> SimdBase<S> for i64x8<S> {
self.simd
.swizzle_dyn_within_blocks_i64x8(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_i64x8(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for i64x8<S> {
#[inline(always)]
Expand Down Expand Up @@ -8386,6 +8531,11 @@ impl<S: Simd> SimdBase<S> for u64x8<S> {
self.simd
.swizzle_dyn_within_blocks_u64x8(self, indices.simd_into(self.simd))
}
#[inline(always)]
fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
self.simd
.swizzle_dyn_precise_u64x8(self, indices.simd_into(self.simd))
}
}
impl<S: Simd> crate::SimdInt<S> for u64x8<S> {
#[inline(always)]
Expand Down
Loading
Loading