Skip to content

Commit 1d8aa13

Browse files
committed
Implement minimumf[32,64} and maximumf{32,64} intrinsics
1 parent 41301c3 commit 1d8aa13

File tree

7 files changed

+83
-1
lines changed

7 files changed

+83
-1
lines changed

compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs

+21
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,27 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
10641064
ret.write_cvalue(fx, val);
10651065
};
10661066

1067+
minimumf32, (v a, v b) {
1068+
let val = fx.bcx.ins().fmin(a, b);
1069+
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f32));
1070+
ret.write_cvalue(fx, val);
1071+
};
1072+
minimumf64, (v a, v b) {
1073+
let val = fx.bcx.ins().fmin(a, b);
1074+
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f64));
1075+
ret.write_cvalue(fx, val);
1076+
};
1077+
maximumf32, (v a, v b) {
1078+
let val = fx.bcx.ins().fmax(a, b);
1079+
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f32));
1080+
ret.write_cvalue(fx, val);
1081+
};
1082+
maximumf64, (v a, v b) {
1083+
let val = fx.bcx.ins().fmax(a, b);
1084+
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f64));
1085+
ret.write_cvalue(fx, val);
1086+
};
1087+
10671088
kw.Try, (v f, v data, v _catch_fn) {
10681089
// FIXME once unwinding is supported, change this to actually catch panics
10691090
let f_sig = fx.bcx.func.import_signature(Signature {

compiler/rustc_codegen_gcc/src/intrinsic/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ fn get_simple_intrinsic<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, name: Symbol) ->
5353
sym::minnumf64 => "fmin",
5454
sym::maxnumf32 => "fmaxf",
5555
sym::maxnumf64 => "fmax",
56+
// FIXME: GCC currently doens't seems to have builtins that propagate NaN
57+
// as required by the {min,max}imum instrinsics. For the mean time
58+
// use the builtins that doens't propagate the NaN
59+
sym::minimumf32 => "fminf",
60+
sym::minimumf64 => "fmin",
61+
sym::maximumf32 => "fmaxf",
62+
sym::maximumf64 => "fmax",
5663
sym::copysignf32 => "copysignf",
5764
sym::copysignf64 => "copysign",
5865
sym::floorf32 => "floorf",

compiler/rustc_codegen_llvm/src/context.rs

+5
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,11 @@ impl CodegenCx<'b, 'tcx> {
640640
ifn!("llvm.maxnum.f32", fn(t_f32, t_f32) -> t_f32);
641641
ifn!("llvm.maxnum.f64", fn(t_f64, t_f64) -> t_f64);
642642

643+
ifn!("llvm.minimum.f32", fn(t_f32, t_f32) -> t_f32);
644+
ifn!("llvm.minimum.f64", fn(t_f64, t_f64) -> t_f64);
645+
ifn!("llvm.maximum.f32", fn(t_f32, t_f32) -> t_f32);
646+
ifn!("llvm.maximum.f64", fn(t_f64, t_f64) -> t_f64);
647+
643648
ifn!("llvm.floor.f32", fn(t_f32) -> t_f32);
644649
ifn!("llvm.floor.f64", fn(t_f64) -> t_f64);
645650

compiler/rustc_codegen_llvm/src/intrinsic.rs

+4
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ fn get_simple_intrinsic(cx: &CodegenCx<'ll, '_>, name: Symbol) -> Option<(&'ll T
5555
sym::minnumf64 => "llvm.minnum.f64",
5656
sym::maxnumf32 => "llvm.maxnum.f32",
5757
sym::maxnumf64 => "llvm.maxnum.f64",
58+
sym::minimumf32 => "llvm.minimum.f32",
59+
sym::minimumf64 => "llvm.minimum.f64",
60+
sym::maximumf32 => "llvm.maximum.f32",
61+
sym::maximumf64 => "llvm.maximum.f64",
5862
sym::copysignf32 => "llvm.copysign.f32",
5963
sym::copysignf64 => "llvm.copysign.f64",
6064
sym::floorf32 => "llvm.floor.f32",

compiler/rustc_span/src/symbol.rs

+4
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,8 @@ symbols! {
810810
masked,
811811
match_beginning_vert,
812812
match_default_bindings,
813+
maximumf32,
814+
maximumf64,
813815
maxnumf32,
814816
maxnumf64,
815817
may_dangle,
@@ -837,6 +839,8 @@ symbols! {
837839
min_const_unsafe_fn,
838840
min_specialization,
839841
min_type_alias_impl_trait,
842+
minimumf32,
843+
minimumf64,
840844
minnumf32,
841845
minnumf64,
842846
mips_target_feature,

compiler/rustc_typeck/src/check/intrinsic.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,12 @@ pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
9898
| sym::minnumf32
9999
| sym::minnumf64
100100
| sym::maxnumf32
101-
| sym::rustc_peek
102101
| sym::maxnumf64
102+
| sym::minimumf32
103+
| sym::minimumf64
104+
| sym::maximumf32
105+
| sym::maximumf64
106+
| sym::rustc_peek
103107
| sym::type_name
104108
| sym::forget
105109
| sym::black_box
@@ -256,6 +260,10 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
256260
sym::minnumf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
257261
sym::maxnumf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
258262
sym::maxnumf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
263+
sym::minimumf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
264+
sym::minimumf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
265+
sym::maximumf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
266+
sym::maximumf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
259267
sym::copysignf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
260268
sym::copysignf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
261269
sym::floorf32 => (0, vec![tcx.types.f32], tcx.types.f32),

library/core/src/intrinsics.rs

+33
Original file line numberDiff line numberDiff line change
@@ -1406,6 +1406,39 @@ extern "rust-intrinsic" {
14061406
/// [`f64::max`]
14071407
pub fn maxnumf64(x: f64, y: f64) -> f64;
14081408

1409+
/// Returns the minimum of two `f32` values.
1410+
///
1411+
/// Note that, unlike most intrinsics, this is safe to call;
1412+
/// it does not require an `unsafe` block.
1413+
/// Therefore, implementations must not require the user to uphold
1414+
/// any safety invariants.
1415+
#[cfg(not(bootstrap))]
1416+
pub fn minimumf32(x: f32, y: f32) -> f32;
1417+
/// Returns the minimum of two `f64` values.
1418+
///
1419+
/// Note that, unlike most intrinsics, this is safe to call;
1420+
/// it does not require an `unsafe` block.
1421+
/// Therefore, implementations must not require the user to uphold
1422+
/// any safety invariants.
1423+
#[cfg(not(bootstrap))]
1424+
pub fn minimumf64(x: f64, y: f64) -> f64;
1425+
/// Returns the maximum of two `f32` values.
1426+
///
1427+
/// Note that, unlike most intrinsics, this is safe to call;
1428+
/// it does not require an `unsafe` block.
1429+
/// Therefore, implementations must not require the user to uphold
1430+
/// any safety invariants.
1431+
#[cfg(not(bootstrap))]
1432+
pub fn maximumf32(x: f32, y: f32) -> f32;
1433+
/// Returns the maximum of two `f64` values.
1434+
///
1435+
/// Note that, unlike most intrinsics, this is safe to call;
1436+
/// it does not require an `unsafe` block.
1437+
/// Therefore, implementations must not require the user to uphold
1438+
/// any safety invariants.
1439+
#[cfg(not(bootstrap))]
1440+
pub fn maximumf64(x: f64, y: f64) -> f64;
1441+
14091442
/// Copies the sign from `y` to `x` for `f32` values.
14101443
///
14111444
/// The stabilized version of this intrinsic is

0 commit comments

Comments
 (0)