Skip to content

Commit 11fb21f

Browse files
committed
Auto merge of #91484 - workingjubilee:simd-remove-autosplats, r=Mark-Simulacrum
Sync portable-simd to remove autosplats This PR syncs portable-simd in up to rust-lang/portable-simd@a838552 in order to address the type inference breakages documented on nightly in #90904 by removing the vector + scalar binary operations (called "autosplats", "broadcasting", or "rank promotion", depending on who you ask) that allow `{scalar} + &'_ {scalar}` to fail in some cases, because it becomes possible the programmer may have meant `{scalar} + &'_ {vector}`. A few quality-of-life improvements make their way in as well: - Lane counts can now go to 64, as LLVM seems to have fixed their miscompilation for those. - `{i,u}8x64` to `__m512i` is now available. - a bunch of `#[must_use]` notes appear throughout the module. - Some implementations, mostly instances of `impl core::ops::{Op}<Simd> for Simd` that aren't `{vector} + {vector}` (e.g. `{vector} + &'_ {vector}`), leverage some generics and `where` bounds now to make them easier to understand by reducing a dozen implementations into one (and make it possible for people to open the docs on less burly devices). - And some internal-only improvements. None of these changes should affect a beta backport, only actual users of `core::simd` (and most aren't even visible in the programmatic sense), though I can extract an even more minimal changeset for beta if necessary. It seemed simpler to just keep moving forward.
2 parents 477fd70 + eef4371 commit 11fb21f

23 files changed

+540
-525
lines changed

library/core/tests/simd.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ fn testing() {
77
let x = f32x4::from_array([1.0, 1.0, 1.0, 1.0]);
88
let y = -x;
99

10-
let h = x * 0.5;
10+
let h = x * f32x4::splat(0.5);
1111

1212
let r = y.abs();
1313
assert_eq!(x, r);

library/portable-simd/CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ SIMD can be quite complex, and even a "simple" issue can be huge. If an issue is
1515

1616
## CI
1717

18-
We currently have 2 CI matrices through Travis CI and GitHub Actions that will automatically build and test your change in order to verify that `std::simd`'s portable API is, in fact, portable. If your change builds locally, but does not build on either, this is likely due to a platform-specific concern that your code has not addressed. Please consult the build logs and address the error, or ask for help if you need it.
18+
We currently use GitHub Actions which will automatically build and test your change in order to verify that `std::simd`'s portable API is, in fact, portable. If your change builds locally, but does not build in CI, this is likely due to a platform-specific concern that your code has not addressed. Please consult the build logs and address the error, or ask for help if you need it.
1919

2020
## Beyond stdsimd
2121

library/portable-simd/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# The Rust standard library's portable SIMD API
2-
[![Build Status](https://travis-ci.com/rust-lang/portable-simd.svg?branch=master)](https://travis-ci.com/rust-lang/portable-simd)
2+
![Build Status](https://github.com/rust-lang/portable-simd/actions/workflows/ci.yml/badge.svg?branch=master)
33

44
Code repository for the [Portable SIMD Project Group](https://github.com/rust-lang/project-portable-simd).
55
Please refer to [CONTRIBUTING.md](./CONTRIBUTING.md) for our contributing guidelines.

library/portable-simd/crates/core_simd/examples/nbody.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ mod nbody {
9797
let sun = &mut sun[0];
9898
for body in rest {
9999
let m_ratio = body.mass / SOLAR_MASS;
100-
sun.v -= body.v * m_ratio;
100+
sun.v -= body.v * Simd::splat(m_ratio);
101101
}
102102
}
103103

@@ -143,14 +143,14 @@ mod nbody {
143143
let mut i = 0;
144144
for j in 0..N_BODIES {
145145
for k in j + 1..N_BODIES {
146-
let f = r[i] * mag[i];
147-
bodies[j].v -= f * bodies[k].mass;
148-
bodies[k].v += f * bodies[j].mass;
146+
let f = r[i] * Simd::splat(mag[i]);
147+
bodies[j].v -= f * Simd::splat(bodies[k].mass);
148+
bodies[k].v += f * Simd::splat(bodies[j].mass);
149149
i += 1
150150
}
151151
}
152152
for body in bodies {
153-
body.x += dt * body.v
153+
body.x += Simd::splat(dt) * body.v
154154
}
155155
}
156156

library/portable-simd/crates/core_simd/src/comparisons.rs

+6
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ where
88
{
99
/// Test if each lane is equal to the corresponding lane in `other`.
1010
#[inline]
11+
#[must_use = "method returns a new mask and does not mutate the original value"]
1112
pub fn lanes_eq(self, other: Self) -> Mask<T::Mask, LANES> {
1213
unsafe { Mask::from_int_unchecked(intrinsics::simd_eq(self, other)) }
1314
}
1415

1516
/// Test if each lane is not equal to the corresponding lane in `other`.
1617
#[inline]
18+
#[must_use = "method returns a new mask and does not mutate the original value"]
1719
pub fn lanes_ne(self, other: Self) -> Mask<T::Mask, LANES> {
1820
unsafe { Mask::from_int_unchecked(intrinsics::simd_ne(self, other)) }
1921
}
@@ -26,24 +28,28 @@ where
2628
{
2729
/// Test if each lane is less than the corresponding lane in `other`.
2830
#[inline]
31+
#[must_use = "method returns a new mask and does not mutate the original value"]
2932
pub fn lanes_lt(self, other: Self) -> Mask<T::Mask, LANES> {
3033
unsafe { Mask::from_int_unchecked(intrinsics::simd_lt(self, other)) }
3134
}
3235

3336
/// Test if each lane is greater than the corresponding lane in `other`.
3437
#[inline]
38+
#[must_use = "method returns a new mask and does not mutate the original value"]
3539
pub fn lanes_gt(self, other: Self) -> Mask<T::Mask, LANES> {
3640
unsafe { Mask::from_int_unchecked(intrinsics::simd_gt(self, other)) }
3741
}
3842

3943
/// Test if each lane is less than or equal to the corresponding lane in `other`.
4044
#[inline]
45+
#[must_use = "method returns a new mask and does not mutate the original value"]
4146
pub fn lanes_le(self, other: Self) -> Mask<T::Mask, LANES> {
4247
unsafe { Mask::from_int_unchecked(intrinsics::simd_le(self, other)) }
4348
}
4449

4550
/// Test if each lane is greater than or equal to the corresponding lane in `other`.
4651
#[inline]
52+
#[must_use = "method returns a new mask and does not mutate the original value"]
4753
pub fn lanes_ge(self, other: Self) -> Mask<T::Mask, LANES> {
4854
unsafe { Mask::from_int_unchecked(intrinsics::simd_ge(self, other)) }
4955
}

library/portable-simd/crates/core_simd/src/lane_count.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,28 @@ impl<const LANES: usize> LaneCount<LANES> {
1515
pub trait SupportedLaneCount: Sealed {
1616
#[doc(hidden)]
1717
type BitMask: Copy + Default + AsRef<[u8]> + AsMut<[u8]>;
18-
19-
#[doc(hidden)]
20-
type IntBitMask;
2118
}
2219

2320
impl<const LANES: usize> Sealed for LaneCount<LANES> {}
2421

2522
impl SupportedLaneCount for LaneCount<1> {
2623
type BitMask = [u8; 1];
27-
type IntBitMask = u8;
2824
}
2925
impl SupportedLaneCount for LaneCount<2> {
3026
type BitMask = [u8; 1];
31-
type IntBitMask = u8;
3227
}
3328
impl SupportedLaneCount for LaneCount<4> {
3429
type BitMask = [u8; 1];
35-
type IntBitMask = u8;
3630
}
3731
impl SupportedLaneCount for LaneCount<8> {
3832
type BitMask = [u8; 1];
39-
type IntBitMask = u8;
4033
}
4134
impl SupportedLaneCount for LaneCount<16> {
4235
type BitMask = [u8; 2];
43-
type IntBitMask = u16;
4436
}
4537
impl SupportedLaneCount for LaneCount<32> {
4638
type BitMask = [u8; 4];
47-
type IntBitMask = u32;
39+
}
40+
impl SupportedLaneCount for LaneCount<64> {
41+
type BitMask = [u8; 8];
4842
}

library/portable-simd/crates/core_simd/src/masks.rs

+24
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ where
129129
/// # Safety
130130
/// All lanes must be either 0 or -1.
131131
#[inline]
132+
#[must_use = "method returns a new mask and does not mutate the original value"]
132133
pub unsafe fn from_int_unchecked(value: Simd<T, LANES>) -> Self {
133134
unsafe { Self(mask_impl::Mask::from_int_unchecked(value)) }
134135
}
@@ -139,6 +140,7 @@ where
139140
/// # Panics
140141
/// Panics if any lane is not 0 or -1.
141142
#[inline]
143+
#[must_use = "method returns a new mask and does not mutate the original value"]
142144
pub fn from_int(value: Simd<T, LANES>) -> Self {
143145
assert!(T::valid(value), "all values must be either 0 or -1",);
144146
unsafe { Self::from_int_unchecked(value) }
@@ -147,6 +149,7 @@ where
147149
/// Converts the mask to a vector of integers, where 0 represents `false` and -1
148150
/// represents `true`.
149151
#[inline]
152+
#[must_use = "method returns a new vector and does not mutate the original value"]
150153
pub fn to_int(self) -> Simd<T, LANES> {
151154
self.0.to_int()
152155
}
@@ -156,6 +159,7 @@ where
156159
/// # Safety
157160
/// `lane` must be less than `LANES`.
158161
#[inline]
162+
#[must_use = "method returns a new bool and does not mutate the original value"]
159163
pub unsafe fn test_unchecked(&self, lane: usize) -> bool {
160164
unsafe { self.0.test_unchecked(lane) }
161165
}
@@ -165,6 +169,7 @@ where
165169
/// # Panics
166170
/// Panics if `lane` is greater than or equal to the number of lanes in the vector.
167171
#[inline]
172+
#[must_use = "method returns a new bool and does not mutate the original value"]
168173
pub fn test(&self, lane: usize) -> bool {
169174
assert!(lane < LANES, "lane index out of range");
170175
unsafe { self.test_unchecked(lane) }
@@ -195,24 +200,30 @@ where
195200

196201
/// Convert this mask to a bitmask, with one bit set per lane.
197202
#[cfg(feature = "generic_const_exprs")]
203+
#[inline]
204+
#[must_use = "method returns a new array and does not mutate the original value"]
198205
pub fn to_bitmask(self) -> [u8; LaneCount::<LANES>::BITMASK_LEN] {
199206
self.0.to_bitmask()
200207
}
201208

202209
/// Convert a bitmask to a mask.
203210
#[cfg(feature = "generic_const_exprs")]
211+
#[inline]
212+
#[must_use = "method returns a new mask and does not mutate the original value"]
204213
pub fn from_bitmask(bitmask: [u8; LaneCount::<LANES>::BITMASK_LEN]) -> Self {
205214
Self(mask_impl::Mask::from_bitmask(bitmask))
206215
}
207216

208217
/// Returns true if any lane is set, or false otherwise.
209218
#[inline]
219+
#[must_use = "method returns a new bool and does not mutate the original value"]
210220
pub fn any(self) -> bool {
211221
self.0.any()
212222
}
213223

214224
/// Returns true if all lanes are set, or false otherwise.
215225
#[inline]
226+
#[must_use = "method returns a new bool and does not mutate the original value"]
216227
pub fn all(self) -> bool {
217228
self.0.all()
218229
}
@@ -245,6 +256,7 @@ where
245256
LaneCount<LANES>: SupportedLaneCount,
246257
{
247258
#[inline]
259+
#[must_use = "method returns a defaulted mask with all lanes set to false (0)"]
248260
fn default() -> Self {
249261
Self::splat(false)
250262
}
@@ -256,6 +268,7 @@ where
256268
LaneCount<LANES>: SupportedLaneCount,
257269
{
258270
#[inline]
271+
#[must_use = "method returns a new bool and does not mutate the original value"]
259272
fn eq(&self, other: &Self) -> bool {
260273
self.0 == other.0
261274
}
@@ -267,6 +280,7 @@ where
267280
LaneCount<LANES>: SupportedLaneCount,
268281
{
269282
#[inline]
283+
#[must_use = "method returns a new Ordering and does not mutate the original value"]
270284
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
271285
self.0.partial_cmp(&other.0)
272286
}
@@ -291,6 +305,7 @@ where
291305
{
292306
type Output = Self;
293307
#[inline]
308+
#[must_use = "method returns a new mask and does not mutate the original value"]
294309
fn bitand(self, rhs: Self) -> Self {
295310
Self(self.0 & rhs.0)
296311
}
@@ -303,6 +318,7 @@ where
303318
{
304319
type Output = Self;
305320
#[inline]
321+
#[must_use = "method returns a new mask and does not mutate the original value"]
306322
fn bitand(self, rhs: bool) -> Self {
307323
self & Self::splat(rhs)
308324
}
@@ -315,6 +331,7 @@ where
315331
{
316332
type Output = Mask<T, LANES>;
317333
#[inline]
334+
#[must_use = "method returns a new mask and does not mutate the original value"]
318335
fn bitand(self, rhs: Mask<T, LANES>) -> Mask<T, LANES> {
319336
Mask::splat(self) & rhs
320337
}
@@ -327,6 +344,7 @@ where
327344
{
328345
type Output = Self;
329346
#[inline]
347+
#[must_use = "method returns a new mask and does not mutate the original value"]
330348
fn bitor(self, rhs: Self) -> Self {
331349
Self(self.0 | rhs.0)
332350
}
@@ -339,6 +357,7 @@ where
339357
{
340358
type Output = Self;
341359
#[inline]
360+
#[must_use = "method returns a new mask and does not mutate the original value"]
342361
fn bitor(self, rhs: bool) -> Self {
343362
self | Self::splat(rhs)
344363
}
@@ -351,6 +370,7 @@ where
351370
{
352371
type Output = Mask<T, LANES>;
353372
#[inline]
373+
#[must_use = "method returns a new mask and does not mutate the original value"]
354374
fn bitor(self, rhs: Mask<T, LANES>) -> Mask<T, LANES> {
355375
Mask::splat(self) | rhs
356376
}
@@ -363,6 +383,7 @@ where
363383
{
364384
type Output = Self;
365385
#[inline]
386+
#[must_use = "method returns a new mask and does not mutate the original value"]
366387
fn bitxor(self, rhs: Self) -> Self::Output {
367388
Self(self.0 ^ rhs.0)
368389
}
@@ -375,6 +396,7 @@ where
375396
{
376397
type Output = Self;
377398
#[inline]
399+
#[must_use = "method returns a new mask and does not mutate the original value"]
378400
fn bitxor(self, rhs: bool) -> Self::Output {
379401
self ^ Self::splat(rhs)
380402
}
@@ -387,6 +409,7 @@ where
387409
{
388410
type Output = Mask<T, LANES>;
389411
#[inline]
412+
#[must_use = "method returns a new mask and does not mutate the original value"]
390413
fn bitxor(self, rhs: Mask<T, LANES>) -> Self::Output {
391414
Mask::splat(self) ^ rhs
392415
}
@@ -399,6 +422,7 @@ where
399422
{
400423
type Output = Mask<T, LANES>;
401424
#[inline]
425+
#[must_use = "method returns a new mask and does not mutate the original value"]
402426
fn not(self) -> Self::Output {
403427
Self(!self.0)
404428
}

0 commit comments

Comments
 (0)