Skip to content

Commit f623e53

Browse files
authored
Merge pull request rust-lang#214 from sadlerap/minmax
simd: implement simd_fmin/fmax
2 parents 2342414 + 1d3ca13 commit f623e53

File tree

4 files changed

+35
-1
lines changed

4 files changed

+35
-1
lines changed

failing-ui-tests.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ src/test/ui/sepcomp/sepcomp-fns.rs
3232
src/test/ui/sepcomp/sepcomp-statics.rs
3333
src/test/ui/simd/generics.rs
3434
src/test/ui/simd/intrinsic/float-math-pass.rs
35-
src/test/ui/simd/intrinsic/float-minmax-pass.rs
3635
src/test/ui/simd/intrinsic/generic-arithmetic-pass.rs
3736
src/test/ui/simd/intrinsic/generic-as.rs
3837
src/test/ui/simd/intrinsic/generic-bitmask-pass.rs

failing-ui-tests12.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ src/test/ui/packed/packed-struct-size.rs
88
src/test/ui/packed/packed-struct-vec.rs
99
src/test/ui/packed/packed-tuple-struct-layout.rs
1010
src/test/ui/simd/array-type.rs
11+
src/test/ui/simd/intrinsic/float-minmax-pass.rs
1112
src/test/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
1213
src/test/ui/simd/intrinsic/generic-cast-pass.rs
1314
src/test/ui/simd/intrinsic/generic-cast-pointer-width.rs

src/builder.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,6 +1505,34 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
15051505
})
15061506
}
15071507

1508+
fn vector_extremum(&mut self, a: RValue<'gcc>, b: RValue<'gcc>, direction: ExtremumOperation) -> RValue<'gcc> {
1509+
let vector_type = a.get_type();
1510+
1511+
// mask out the NaNs in b and replace them with the corresponding lane in a, so when a and
1512+
// b get compared & spliced together, we get the numeric values instead of NaNs.
1513+
let b_nan_mask = self.context.new_comparison(None, ComparisonOp::NotEquals, b, b);
1514+
let mask_type = b_nan_mask.get_type();
1515+
let b_nan_mask_inverted = self.context.new_unary_op(None, UnaryOp::BitwiseNegate, mask_type, b_nan_mask);
1516+
let a_cast = self.context.new_bitcast(None, a, mask_type);
1517+
let b_cast = self.context.new_bitcast(None, b, mask_type);
1518+
let res = (b_nan_mask & a_cast) | (b_nan_mask_inverted & b_cast);
1519+
let b = self.context.new_bitcast(None, res, vector_type);
1520+
1521+
// now do the actual comparison
1522+
let comparison_op = match direction {
1523+
ExtremumOperation::Min => ComparisonOp::LessThan,
1524+
ExtremumOperation::Max => ComparisonOp::GreaterThan,
1525+
};
1526+
let cmp = self.context.new_comparison(None, comparison_op, a, b);
1527+
let cmp_inverted = self.context.new_unary_op(None, UnaryOp::BitwiseNegate, cmp.get_type(), cmp);
1528+
let res = (cmp & a_cast) | (cmp_inverted & res);
1529+
self.context.new_bitcast(None, res, vector_type)
1530+
}
1531+
1532+
pub fn vector_fmin(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
1533+
self.vector_extremum(a, b, ExtremumOperation::Min)
1534+
}
1535+
15081536
#[cfg(feature="master")]
15091537
pub fn vector_reduce_fmin(&mut self, src: RValue<'gcc>) -> RValue<'gcc> {
15101538
let vector_type = src.get_type().unqualified().dyncast_vector().expect("vector type");
@@ -1525,6 +1553,10 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
15251553
unimplemented!();
15261554
}
15271555

1556+
pub fn vector_fmax(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
1557+
self.vector_extremum(a, b, ExtremumOperation::Max)
1558+
}
1559+
15281560
#[cfg(feature="master")]
15291561
pub fn vector_reduce_fmax(&mut self, src: RValue<'gcc>) -> RValue<'gcc> {
15301562
let vector_type = src.get_type().unqualified().dyncast_vector().expect("vector type");

src/intrinsic/simd.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
492492
simd_and: Uint, Int => and;
493493
simd_or: Uint, Int => or; // FIXME(antoyo): calling `or` might not work on vectors.
494494
simd_xor: Uint, Int => xor;
495+
simd_fmin: Float => vector_fmin;
496+
simd_fmax: Float => vector_fmax;
495497
}
496498

497499
macro_rules! arith_unary {

0 commit comments

Comments
 (0)