From c9636158d91dda241eca5a729fcb7e2a45d7a950 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Mon, 6 Jun 2022 12:16:17 -0700 Subject: [PATCH 1/2] Change `Simd::splat` to not generate a loop This fixes poor codegen in some circumstances for `u16x8::splat` on x86_64 https://rust-lang.zulipchat.com/#narrow/stream/257879-project-portable-simd/topic/Very.20bad.20.60u16x8.3A.3Asplat.60.20codegen.20on.20x86_64 --- crates/core_simd/src/vector.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs index fac7dca51f4b0..8379135826d13 100644 --- a/crates/core_simd/src/vector.rs +++ b/crates/core_simd/src/vector.rs @@ -9,8 +9,9 @@ pub use uint::*; // Vectors of pointers are not for public use at the current time. pub(crate) mod ptr; -use crate::simd::intrinsics; -use crate::simd::{LaneCount, Mask, MaskElement, SimdPartialOrd, SupportedLaneCount}; +use crate::simd::{ + intrinsics, LaneCount, Mask, MaskElement, SimdPartialOrd, SupportedLaneCount, Swizzle, +}; /// A SIMD vector of `LANES` elements of type `T`. `Simd` has the same shape as [`[T; N]`](array), but operates like `T`. /// @@ -123,8 +124,12 @@ where /// let v = u32x4::splat(8); /// assert_eq!(v.as_array(), &[8, 8, 8, 8]); /// ``` - pub const fn splat(value: T) -> Self { - Self([value; LANES]) + pub fn splat(value: T) -> Self { + struct Splat; + impl Swizzle<1, LANES> for Splat { + const INDEX: [usize; LANES] = [0; LANES]; + } + Splat::swizzle(Simd::::from([value])) } /// Returns an array reference containing the entire SIMD vector. From f7412ad7b918578864f4d9a0fc24279f7fbebc31 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Mon, 6 Jun 2022 12:43:29 -0700 Subject: [PATCH 2/2] add workaround comment in `Simd::splat` --- crates/core_simd/src/vector.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs index 8379135826d13..19bf45385db0d 100644 --- a/crates/core_simd/src/vector.rs +++ b/crates/core_simd/src/vector.rs @@ -125,6 +125,8 @@ where /// assert_eq!(v.as_array(), &[8, 8, 8, 8]); /// ``` pub fn splat(value: T) -> Self { + // This is a workaround for `[value; LANES]` generating a loop: + // https://github.com/rust-lang/rust/issues/97804 struct Splat; impl Swizzle<1, LANES> for Splat { const INDEX: [usize; LANES] = [0; LANES];