]> git.lizzy.rs Git - rust.git/commitdiff
Change `Simd::splat` to not generate a loop
authorJacob Lifshay <programmerjake@gmail.com>
Mon, 6 Jun 2022 19:16:17 +0000 (12:16 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Mon, 6 Jun 2022 19:16:17 +0000 (12:16 -0700)
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

index fac7dca51f4b0e2a798b7d2e6dff7a05a9b3c4c4..8379135826d1362bfd4dd952a17bc455e78d559c 100644 (file)
@@ -9,8 +9,9 @@
 // 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<T, N>` has the same shape as [`[T; N]`](array), but operates like `T`.
 ///
@@ -123,8 +124,12 @@ pub const fn lanes(&self) -> usize {
     /// 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<const LANES: usize> Swizzle<1, LANES> for Splat {
+            const INDEX: [usize; LANES] = [0; LANES];
+        }
+        Splat::swizzle(Simd::<T, 1>::from([value]))
     }
 
     /// Returns an array reference containing the entire SIMD vector.