Skip to content

Commit 2bcacd6

Browse files
Rollup merge of rust-lang#155189 - RalfJung:reduce-minmax-float, r=petrochenkov
simd_reduce_min/max: remove float support LLVM currently doesn't have an intrinsic with the right semantics here (see llvm/llvm-project#185827). The only remaining user of this intrinsic with float types is portable-simd and it's easier to implement a fallback there than here, so I opted for making the intrinsic int-only. I kept around the float support in cranelift and Miri because there it already has the desired semantics (matching scalar min/max). Fixes rust-lang#153395 ~~Blocked on rust-lang/portable-simd#515
2 parents ca00f33 + ad7ddbc commit 2bcacd6

6 files changed

Lines changed: 19 additions & 86 deletions

File tree

compiler/rustc_codegen_gcc/src/builder.rs

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2313,67 +2313,10 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
23132313
self.vector_extremum(a, b, ExtremumOperation::Min)
23142314
}
23152315

2316-
#[cfg(feature = "master")]
2317-
pub fn vector_reduce_fmin(&mut self, src: RValue<'gcc>) -> RValue<'gcc> {
2318-
let vector_type = src.get_type().unqualified().dyncast_vector().expect("vector type");
2319-
let element_count = vector_type.get_num_units();
2320-
let mut acc = self
2321-
.context
2322-
.new_vector_access(self.location, src, self.context.new_rvalue_zero(self.int_type))
2323-
.to_rvalue();
2324-
for i in 1..element_count {
2325-
let elem = self
2326-
.context
2327-
.new_vector_access(
2328-
self.location,
2329-
src,
2330-
self.context.new_rvalue_from_int(self.int_type, i as _),
2331-
)
2332-
.to_rvalue();
2333-
let cmp = self.context.new_comparison(self.location, ComparisonOp::LessThan, acc, elem);
2334-
acc = self.select(cmp, acc, elem);
2335-
}
2336-
acc
2337-
}
2338-
2339-
#[cfg(not(feature = "master"))]
2340-
pub fn vector_reduce_fmin(&mut self, _src: RValue<'gcc>) -> RValue<'gcc> {
2341-
unimplemented!();
2342-
}
2343-
23442316
pub fn vector_maximum_number_nsz(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
23452317
self.vector_extremum(a, b, ExtremumOperation::Max)
23462318
}
23472319

2348-
#[cfg(feature = "master")]
2349-
pub fn vector_reduce_fmax(&mut self, src: RValue<'gcc>) -> RValue<'gcc> {
2350-
let vector_type = src.get_type().unqualified().dyncast_vector().expect("vector type");
2351-
let element_count = vector_type.get_num_units();
2352-
let mut acc = self
2353-
.context
2354-
.new_vector_access(self.location, src, self.context.new_rvalue_zero(self.int_type))
2355-
.to_rvalue();
2356-
for i in 1..element_count {
2357-
let elem = self
2358-
.context
2359-
.new_vector_access(
2360-
self.location,
2361-
src,
2362-
self.context.new_rvalue_from_int(self.int_type, i as _),
2363-
)
2364-
.to_rvalue();
2365-
let cmp =
2366-
self.context.new_comparison(self.location, ComparisonOp::GreaterThan, acc, elem);
2367-
acc = self.select(cmp, acc, elem);
2368-
}
2369-
acc
2370-
}
2371-
2372-
#[cfg(not(feature = "master"))]
2373-
pub fn vector_reduce_fmax(&mut self, _src: RValue<'gcc>) -> RValue<'gcc> {
2374-
unimplemented!();
2375-
}
2376-
23772320
pub fn vector_select(
23782321
&mut self,
23792322
cond: RValue<'gcc>,

compiler/rustc_codegen_gcc/src/intrinsic/simd.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,15 +1422,14 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
14221422
);
14231423

14241424
macro_rules! minmax_red {
1425-
($name:ident: $int_red:ident, $float_red:ident) => {
1425+
($name:ident: $int_red:ident) => {
14261426
if name == sym::$name {
14271427
require!(
14281428
ret_ty == in_elem,
14291429
InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
14301430
);
14311431
return match *in_elem.kind() {
14321432
ty::Int(_) | ty::Uint(_) => Ok(bx.$int_red(args[0].immediate())),
1433-
ty::Float(_) => Ok(bx.$float_red(args[0].immediate())),
14341433
_ => return_error!(InvalidMonomorphization::UnsupportedSymbol {
14351434
span,
14361435
name,
@@ -1444,8 +1443,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
14441443
};
14451444
}
14461445

1447-
minmax_red!(simd_reduce_min: vector_reduce_min, vector_reduce_fmin);
1448-
minmax_red!(simd_reduce_max: vector_reduce_max, vector_reduce_fmax);
1446+
minmax_red!(simd_reduce_min: vector_reduce_min);
1447+
minmax_red!(simd_reduce_max: vector_reduce_max);
14491448

14501449
macro_rules! bitwise_red {
14511450
($name:ident : $op:expr, $boolean:expr) => {

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,12 +1668,6 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
16681668
pub(crate) fn vector_reduce_xor(&mut self, src: &'ll Value) -> &'ll Value {
16691669
self.call_intrinsic("llvm.vector.reduce.xor", &[self.val_ty(src)], &[src])
16701670
}
1671-
pub(crate) fn vector_reduce_fmin(&mut self, src: &'ll Value) -> &'ll Value {
1672-
self.call_intrinsic("llvm.vector.reduce.fmin", &[self.val_ty(src)], &[src])
1673-
}
1674-
pub(crate) fn vector_reduce_fmax(&mut self, src: &'ll Value) -> &'ll Value {
1675-
self.call_intrinsic("llvm.vector.reduce.fmax", &[self.val_ty(src)], &[src])
1676-
}
16771671
pub(crate) fn vector_reduce_min(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
16781672
self.call_intrinsic(
16791673
if is_signed { "llvm.vector.reduce.smin" } else { "llvm.vector.reduce.umin" },

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2922,7 +2922,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
29222922
);
29232923

29242924
macro_rules! minmax_red {
2925-
($name:ident: $int_red:ident, $float_red:ident) => {
2925+
($name:ident: $int_red:ident) => {
29262926
if name == sym::$name {
29272927
require!(
29282928
ret_ty == in_elem,
@@ -2931,7 +2931,6 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
29312931
return match in_elem.kind() {
29322932
ty::Int(_i) => Ok(bx.$int_red(args[0].immediate(), true)),
29332933
ty::Uint(_u) => Ok(bx.$int_red(args[0].immediate(), false)),
2934-
ty::Float(_f) => Ok(bx.$float_red(args[0].immediate())),
29352934
_ => return_error!(InvalidMonomorphization::UnsupportedSymbol {
29362935
span,
29372936
name,
@@ -2945,8 +2944,9 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
29452944
};
29462945
}
29472946

2948-
minmax_red!(simd_reduce_min: vector_reduce_min, vector_reduce_fmin);
2949-
minmax_red!(simd_reduce_max: vector_reduce_max, vector_reduce_fmax);
2947+
// Currently no support for float due to <https://github.com/llvm/llvm-project/issues/185827>.
2948+
minmax_red!(simd_reduce_min: vector_reduce_min);
2949+
minmax_red!(simd_reduce_max: vector_reduce_max);
29502950

29512951
macro_rules! bitwise_red {
29522952
($name:ident : $red:ident, $boolean:expr) => {

library/core/src/intrinsics/simd/mod.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ pub unsafe fn simd_reduce_mul_unordered<T, U>(x: T) -> U;
520520

521521
/// Checks if all mask values are true.
522522
///
523-
/// `T` must be a vector of integer primitive types.
523+
/// `T` must be a vector of integers.
524524
///
525525
/// # Safety
526526
/// `x` must contain only `0` or `!0`.
@@ -530,7 +530,7 @@ pub const unsafe fn simd_reduce_all<T>(x: T) -> bool;
530530

531531
/// Checks if any mask value is true.
532532
///
533-
/// `T` must be a vector of integer primitive types.
533+
/// `T` must be a vector of integers.
534534
///
535535
/// # Safety
536536
/// `x` must contain only `0` or `!0`.
@@ -540,29 +540,25 @@ pub const unsafe fn simd_reduce_any<T>(x: T) -> bool;
540540

541541
/// Returns the maximum element of a vector.
542542
///
543-
/// `T` must be a vector of integers or floats.
543+
/// `T` must be a vector of integers.
544544
///
545545
/// `U` must be the element type of `T`.
546-
///
547-
/// For floating-point values, uses IEEE-754 `maxNum`.
548546
#[rustc_intrinsic]
549547
#[rustc_nounwind]
550548
pub const unsafe fn simd_reduce_max<T, U>(x: T) -> U;
551549

552550
/// Returns the minimum element of a vector.
553551
///
554-
/// `T` must be a vector of integers or floats.
552+
/// `T` must be a vector of integers.
555553
///
556554
/// `U` must be the element type of `T`.
557-
///
558-
/// For floating-point values, uses IEEE-754 `minNum`.
559555
#[rustc_intrinsic]
560556
#[rustc_nounwind]
561557
pub const unsafe fn simd_reduce_min<T, U>(x: T) -> U;
562558

563559
/// Logical "and"s all elements together.
564560
///
565-
/// `T` must be a vector of integers or floats.
561+
/// `T` must be a vector of integers.
566562
///
567563
/// `U` must be the element type of `T`.
568564
#[rustc_intrinsic]
@@ -571,7 +567,7 @@ pub const unsafe fn simd_reduce_and<T, U>(x: T) -> U;
571567

572568
/// Logical "ors" all elements together.
573569
///
574-
/// `T` must be a vector of integers or floats.
570+
/// `T` must be a vector of integers.
575571
///
576572
/// `U` must be the element type of `T`.
577573
#[rustc_intrinsic]
@@ -580,7 +576,7 @@ pub const unsafe fn simd_reduce_or<T, U>(x: T) -> U;
580576

581577
/// Logical "exclusive ors" all elements together.
582578
///
583-
/// `T` must be a vector of integers or floats.
579+
/// `T` must be a vector of integers.
584580
///
585581
/// `U` must be the element type of `T`.
586582
#[rustc_intrinsic]

tests/ui/simd/intrinsic/generic-reduction-pass.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,11 @@ const fn ordered() {
109109
let r: f32 = simd_reduce_mul_ordered(x, 2.);
110110
assert_eq!(r, -48_f32);
111111

112-
let r: f32 = simd_reduce_min(x);
113-
assert_eq!(r, -2_f32);
114-
let r: f32 = simd_reduce_max(x);
115-
assert_eq!(r, 4_f32);
112+
// FIXME: re-enable when the intrinsic works on floats again.
113+
// let r: f32 = simd_reduce_min(x);
114+
// assert_eq!(r, -2_f32);
115+
// let r: f32 = simd_reduce_max(x);
116+
// assert_eq!(r, 4_f32);
116117
}
117118

118119
unsafe {

0 commit comments

Comments
 (0)