@@ -163,21 +163,31 @@ where
163163 /// Converts an array to a SIMD vector.
164164 pub const fn from_array ( array : [ T ; LANES ] ) -> Self {
165165 // SAFETY: Transmuting between `Simd<T, LANES>` and `[T; LANES]`
166- // is always valid.
166+ // is always valid. We need to use `read_unaligned` here, since
167+ // the array may have a lower alignment than the vector.
168+ //
169+ // FIXME: We currently use a pointer read instead of `transmute_copy` because
170+ // it results in better codegen with optimizations disabled, but we should
171+ // probably just use `transmute` once that works on const generic types.
167172 //
168173 // NOTE: This deliberately doesn't just use `Self(array)`, see the comment
169174 // on the struct definition for details.
170- unsafe { core :: mem :: transmute_copy ( & array) }
175+ unsafe { ( & array as * const [ T ; LANES ] as * const Self ) . read_unaligned ( ) }
171176 }
172177
173178 /// Converts a SIMD vector to an array.
174179 pub const fn to_array ( self ) -> [ T ; LANES ] {
175180 // SAFETY: Transmuting between `Simd<T, LANES>` and `[T; LANES]`
176- // is always valid.
181+ // is always valid. No need to use `read_unaligned` here, since
182+ // the vector never has a lower alignment than the array.
183+ //
184+ // FIXME: We currently use a pointer read instead of `transmute_copy` because
185+ // it results in better codegen with optimizations disabled, but we should
186+ // probably just use `transmute` once that works on const generic types.
177187 //
178188 // NOTE: This deliberately doesn't just use `self.0`, see the comment
179189 // on the struct definition for details.
180- unsafe { core :: mem :: transmute_copy ( & self ) }
190+ unsafe { ( & self as * const Self as * const [ T ; LANES ] ) . read ( ) }
181191 }
182192
183193 /// Converts a slice to a SIMD vector containing `slice[..LANES]`.
0 commit comments