Skip to content

Commit 5d08e76

Browse files
Rollup merge of #154043 - RalfJung:simd-min-max, r=Amanieu,calebzulawski,antoyo
simd_fmin/fmax: make semantics and name consistent with scalar intrinsics This is the SIMD version of rust-lang/rust#153343: change the documented semantics of the SIMD float min/max intrinsics to that of the scalar intrinsics, and also make the name consistent. The overall semantic change this amounts to is that we restrict the non-determinism: the old semantics effectively mean "when one input is an SNaN, the result non-deterministically is a NaN or the other input"; the new semantics say that in this case the other input must be returned. For all other cases, old and new semantics are equivalent. This means all users of these intrinsics that were correct with the old semantics are still correct: the overall set of possible behaviors has become smaller, no new possible behaviors are being added. In terms of providers of this API: - Miri, GCC, and cranelift already implement the new semantics, so no changes are needed. - LLVM is adjusted to use `minimumnum nsz` instead of `minnum`, thus giving us the new semantics. In terms of consumers of this API: - Portable SIMD almost certainly wants to match the scalar behavior, so this is strictly a bugfix here. - Stdarch mostly stopped using the intrinsic, except on nvptx, where arguably the new semantics are closer to what we actually want than the old semantics (rust-lang/stdarch#2056). Q: Should there be an `f` in the intrinsic name to indicate that it is for floats? E.g., `simd_fminimum_number_nsz`? Also see rust-lang/rust#153395.
2 parents 383705e + 646b64f commit 5d08e76

2 files changed

Lines changed: 9 additions & 6 deletions

File tree

src/builder.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2278,6 +2278,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
22782278
})
22792279
}
22802280

2281+
/// Emits a SIMD min/max operation for floats. The semantics for each lane are: if one
2282+
/// side is NaN (QNaN or SNaN), the other side is returned.
22812283
fn vector_extremum(
22822284
&mut self,
22832285
a: RValue<'gcc>,
@@ -2286,8 +2288,9 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
22862288
) -> RValue<'gcc> {
22872289
let vector_type = a.get_type();
22882290

2289-
// mask out the NaNs in b and replace them with the corresponding lane in a, so when a and
2290-
// b get compared & spliced together, we get the numeric values instead of NaNs.
2291+
// Mask out the NaNs (both QNaN and SNaN) in b and replace them with the corresponding lane
2292+
// in a, so when a and b get compared & spliced together, we get the numeric values instead
2293+
// of NaNs.
22912294
let b_nan_mask = self.context.new_comparison(self.location, ComparisonOp::NotEquals, b, b);
22922295
let mask_type = b_nan_mask.get_type();
22932296
let b_nan_mask_inverted =
@@ -2309,7 +2312,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
23092312
self.context.new_bitcast(self.location, res, vector_type)
23102313
}
23112314

2312-
pub fn vector_fmin(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
2315+
pub fn vector_minimum_number_nsz(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
23132316
self.vector_extremum(a, b, ExtremumOperation::Min)
23142317
}
23152318

@@ -2341,7 +2344,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
23412344
unimplemented!();
23422345
}
23432346

2344-
pub fn vector_fmax(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
2347+
pub fn vector_maximum_number_nsz(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
23452348
self.vector_extremum(a, b, ExtremumOperation::Max)
23462349
}
23472350

src/intrinsic/simd.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,8 +1222,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
12221222
simd_and: Uint, Int => and;
12231223
simd_or: Uint, Int => or; // FIXME(antoyo): calling `or` might not work on vectors.
12241224
simd_xor: Uint, Int => xor;
1225-
simd_fmin: Float => vector_fmin;
1226-
simd_fmax: Float => vector_fmax;
1225+
simd_minimum_number_nsz: Float => vector_minimum_number_nsz;
1226+
simd_maximum_number_nsz: Float => vector_maximum_number_nsz;
12271227
}
12281228

12291229
macro_rules! arith_unary {

0 commit comments

Comments
 (0)