Merge pull request #214 from sadlerap/minmax
simd: implement simd_fmin/fmax
This commit is contained in:
commit
f623e5325a
@ -32,7 +32,6 @@ src/test/ui/sepcomp/sepcomp-fns.rs
|
|||||||
src/test/ui/sepcomp/sepcomp-statics.rs
|
src/test/ui/sepcomp/sepcomp-statics.rs
|
||||||
src/test/ui/simd/generics.rs
|
src/test/ui/simd/generics.rs
|
||||||
src/test/ui/simd/intrinsic/float-math-pass.rs
|
src/test/ui/simd/intrinsic/float-math-pass.rs
|
||||||
src/test/ui/simd/intrinsic/float-minmax-pass.rs
|
|
||||||
src/test/ui/simd/intrinsic/generic-arithmetic-pass.rs
|
src/test/ui/simd/intrinsic/generic-arithmetic-pass.rs
|
||||||
src/test/ui/simd/intrinsic/generic-as.rs
|
src/test/ui/simd/intrinsic/generic-as.rs
|
||||||
src/test/ui/simd/intrinsic/generic-bitmask-pass.rs
|
src/test/ui/simd/intrinsic/generic-bitmask-pass.rs
|
||||||
|
@ -8,6 +8,7 @@ src/test/ui/packed/packed-struct-size.rs
|
|||||||
src/test/ui/packed/packed-struct-vec.rs
|
src/test/ui/packed/packed-struct-vec.rs
|
||||||
src/test/ui/packed/packed-tuple-struct-layout.rs
|
src/test/ui/packed/packed-tuple-struct-layout.rs
|
||||||
src/test/ui/simd/array-type.rs
|
src/test/ui/simd/array-type.rs
|
||||||
|
src/test/ui/simd/intrinsic/float-minmax-pass.rs
|
||||||
src/test/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
|
src/test/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
|
||||||
src/test/ui/simd/intrinsic/generic-cast-pass.rs
|
src/test/ui/simd/intrinsic/generic-cast-pass.rs
|
||||||
src/test/ui/simd/intrinsic/generic-cast-pointer-width.rs
|
src/test/ui/simd/intrinsic/generic-cast-pointer-width.rs
|
||||||
|
@ -1505,6 +1505,34 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn vector_extremum(&mut self, a: RValue<'gcc>, b: RValue<'gcc>, direction: ExtremumOperation) -> RValue<'gcc> {
|
||||||
|
let vector_type = a.get_type();
|
||||||
|
|
||||||
|
// mask out the NaNs in b and replace them with the corresponding lane in a, so when a and
|
||||||
|
// b get compared & spliced together, we get the numeric values instead of NaNs.
|
||||||
|
let b_nan_mask = self.context.new_comparison(None, ComparisonOp::NotEquals, b, b);
|
||||||
|
let mask_type = b_nan_mask.get_type();
|
||||||
|
let b_nan_mask_inverted = self.context.new_unary_op(None, UnaryOp::BitwiseNegate, mask_type, b_nan_mask);
|
||||||
|
let a_cast = self.context.new_bitcast(None, a, mask_type);
|
||||||
|
let b_cast = self.context.new_bitcast(None, b, mask_type);
|
||||||
|
let res = (b_nan_mask & a_cast) | (b_nan_mask_inverted & b_cast);
|
||||||
|
let b = self.context.new_bitcast(None, res, vector_type);
|
||||||
|
|
||||||
|
// now do the actual comparison
|
||||||
|
let comparison_op = match direction {
|
||||||
|
ExtremumOperation::Min => ComparisonOp::LessThan,
|
||||||
|
ExtremumOperation::Max => ComparisonOp::GreaterThan,
|
||||||
|
};
|
||||||
|
let cmp = self.context.new_comparison(None, comparison_op, a, b);
|
||||||
|
let cmp_inverted = self.context.new_unary_op(None, UnaryOp::BitwiseNegate, cmp.get_type(), cmp);
|
||||||
|
let res = (cmp & a_cast) | (cmp_inverted & res);
|
||||||
|
self.context.new_bitcast(None, res, vector_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn vector_fmin(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
|
||||||
|
self.vector_extremum(a, b, ExtremumOperation::Min)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature="master")]
|
#[cfg(feature="master")]
|
||||||
pub fn vector_reduce_fmin(&mut self, src: RValue<'gcc>) -> RValue<'gcc> {
|
pub fn vector_reduce_fmin(&mut self, src: RValue<'gcc>) -> RValue<'gcc> {
|
||||||
let vector_type = src.get_type().unqualified().dyncast_vector().expect("vector type");
|
let vector_type = src.get_type().unqualified().dyncast_vector().expect("vector type");
|
||||||
@ -1525,6 +1553,10 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
|||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn vector_fmax(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
|
||||||
|
self.vector_extremum(a, b, ExtremumOperation::Max)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature="master")]
|
#[cfg(feature="master")]
|
||||||
pub fn vector_reduce_fmax(&mut self, src: RValue<'gcc>) -> RValue<'gcc> {
|
pub fn vector_reduce_fmax(&mut self, src: RValue<'gcc>) -> RValue<'gcc> {
|
||||||
let vector_type = src.get_type().unqualified().dyncast_vector().expect("vector type");
|
let vector_type = src.get_type().unqualified().dyncast_vector().expect("vector type");
|
||||||
|
@ -492,6 +492,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
|
|||||||
simd_and: Uint, Int => and;
|
simd_and: Uint, Int => and;
|
||||||
simd_or: Uint, Int => or; // FIXME(antoyo): calling `or` might not work on vectors.
|
simd_or: Uint, Int => or; // FIXME(antoyo): calling `or` might not work on vectors.
|
||||||
simd_xor: Uint, Int => xor;
|
simd_xor: Uint, Int => xor;
|
||||||
|
simd_fmin: Float => vector_fmin;
|
||||||
|
simd_fmax: Float => vector_fmax;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! arith_unary {
|
macro_rules! arith_unary {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user