Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit e21748d

Browse files
committed
Add fminimum, fmaximum, fminimum_num, and fmaximum_num
These functions represent new operations from IEEE 754-2019. Introduce them for all float sizes.
1 parent 2d3bd6c commit e21748d

23 files changed

+997
-31
lines changed

crates/libm-macros/src/shared.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,17 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
4747
FloatTy::F16,
4848
Signature { args: &[Ty::F16, Ty::F16], returns: &[Ty::F16] },
4949
None,
50-
&["copysignf16", "fdimf16", "fmaxf16", "fminf16", "fmodf16"],
50+
&[
51+
"copysignf16",
52+
"fdimf16",
53+
"fmaxf16",
54+
"fmaximum_numf16",
55+
"fmaximumf16",
56+
"fminf16",
57+
"fminimum_numf16",
58+
"fminimumf16",
59+
"fmodf16",
60+
],
5161
),
5262
(
5363
// `(f32, f32) -> f32`
@@ -59,7 +69,11 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
5969
"copysignf",
6070
"fdimf",
6171
"fmaxf",
72+
"fmaximum_numf",
73+
"fmaximumf",
6274
"fminf",
75+
"fminimum_numf",
76+
"fminimumf",
6377
"fmodf",
6478
"hypotf",
6579
"nextafterf",
@@ -77,7 +91,11 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
7791
"copysign",
7892
"fdim",
7993
"fmax",
94+
"fmaximum",
95+
"fmaximum_num",
8096
"fmin",
97+
"fminimum",
98+
"fminimum_num",
8199
"fmod",
82100
"hypot",
83101
"nextafter",
@@ -90,7 +108,17 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
90108
FloatTy::F128,
91109
Signature { args: &[Ty::F128, Ty::F128], returns: &[Ty::F128] },
92110
None,
93-
&["copysignf128", "fdimf128", "fmaxf128", "fminf128", "fmodf128"],
111+
&[
112+
"copysignf128",
113+
"fdimf128",
114+
"fmaxf128",
115+
"fmaximum_numf128",
116+
"fmaximumf128",
117+
"fminf128",
118+
"fminimum_numf128",
119+
"fminimumf128",
120+
"fmodf128",
121+
],
94122
),
95123
(
96124
// `(f32, f32, f32) -> f32`

crates/libm-test/benches/icount.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,26 @@ main!(
207207
icount_bench_fmaxf128_group,
208208
icount_bench_fmaxf16_group,
209209
icount_bench_fmaxf_group,
210+
icount_bench_fmaximum_group,
211+
icount_bench_fmaximum_num_group,
212+
icount_bench_fmaximum_numf128_group,
213+
icount_bench_fmaximum_numf16_group,
214+
icount_bench_fmaximum_numf_group,
215+
icount_bench_fmaximumf128_group,
216+
icount_bench_fmaximumf16_group,
217+
icount_bench_fmaximumf_group,
210218
icount_bench_fmin_group,
211219
icount_bench_fminf128_group,
212220
icount_bench_fminf16_group,
213221
icount_bench_fminf_group,
222+
icount_bench_fminimum_group,
223+
icount_bench_fminimum_num_group,
224+
icount_bench_fminimum_numf128_group,
225+
icount_bench_fminimum_numf16_group,
226+
icount_bench_fminimum_numf_group,
227+
icount_bench_fminimumf128_group,
228+
icount_bench_fminimumf16_group,
229+
icount_bench_fminimumf_group,
214230
icount_bench_fmod_group,
215231
icount_bench_fmodf128_group,
216232
icount_bench_fmodf16_group,

crates/libm-test/benches/random.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,24 @@ libm_macros::for_each_function! {
130130
| fmaf128
131131
| fmaxf128
132132
| fmaxf16
133+
| fmaximum
134+
| fmaximum_num
135+
| fmaximum_numf
136+
| fmaximum_numf128
137+
| fmaximum_numf16
138+
| fmaximumf
139+
| fmaximumf128
140+
| fmaximumf16
133141
| fminf128
134142
| fminf16
143+
| fminimum
144+
| fminimum_num
145+
| fminimum_numf
146+
| fminimum_numf128
147+
| fminimum_numf16
148+
| fminimumf
149+
| fminimumf128
150+
| fminimumf16
135151
| fmodf128
136152
| fmodf16
137153
| ldexpf128

crates/libm-test/src/domain.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,11 @@ pub fn get_domain<F: Float, I: Int>(
221221
BaseName::Floor => &EitherPrim::UNBOUNDED1[..],
222222
BaseName::Fma => &EitherPrim::UNBOUNDED3[..],
223223
BaseName::Fmax => &EitherPrim::UNBOUNDED2[..],
224+
BaseName::Fmaximum => &EitherPrim::UNBOUNDED2[..],
225+
BaseName::FmaximumNum => &EitherPrim::UNBOUNDED2[..],
224226
BaseName::Fmin => &EitherPrim::UNBOUNDED2[..],
227+
BaseName::Fminimum => &EitherPrim::UNBOUNDED2[..],
228+
BaseName::FminimumNum => &EitherPrim::UNBOUNDED2[..],
225229
BaseName::Fmod => &EitherPrim::UNBOUNDED2[..],
226230
BaseName::Hypot => &EitherPrim::UNBOUNDED2[..],
227231
BaseName::Ilogb => &EitherPrim::UNBOUNDED1[..],

crates/libm-test/src/gen/case_list.rs

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,39 +293,111 @@ fn fmaf128_cases() -> Vec<TestCase<op::fmaf128::Routine>> {
293293
v
294294
}
295295

296-
fn fmax_cases() -> Vec<TestCase<op::fmax::Routine>> {
296+
#[cfg(f16_enabled)]
297+
fn fmaxf16_cases() -> Vec<TestCase<op::fmaxf16::Routine>> {
297298
vec![]
298299
}
299300

300301
fn fmaxf_cases() -> Vec<TestCase<op::fmaxf::Routine>> {
301302
vec![]
302303
}
303304

305+
fn fmax_cases() -> Vec<TestCase<op::fmax::Routine>> {
306+
vec![]
307+
}
308+
304309
#[cfg(f128_enabled)]
305310
fn fmaxf128_cases() -> Vec<TestCase<op::fmaxf128::Routine>> {
306311
vec![]
307312
}
308313

309314
#[cfg(f16_enabled)]
310-
fn fmaxf16_cases() -> Vec<TestCase<op::fmaxf16::Routine>> {
315+
fn fmaximumf16_cases() -> Vec<TestCase<op::fmaximumf16::Routine>> {
311316
vec![]
312317
}
313318

314-
fn fmin_cases() -> Vec<TestCase<op::fmin::Routine>> {
319+
fn fmaximumf_cases() -> Vec<TestCase<op::fmaximumf::Routine>> {
320+
vec![]
321+
}
322+
323+
fn fmaximum_cases() -> Vec<TestCase<op::fmaximum::Routine>> {
324+
vec![]
325+
}
326+
327+
#[cfg(f128_enabled)]
328+
fn fmaximumf128_cases() -> Vec<TestCase<op::fmaximumf128::Routine>> {
329+
vec![]
330+
}
331+
332+
#[cfg(f16_enabled)]
333+
fn fmaximum_numf16_cases() -> Vec<TestCase<op::fmaximum_numf16::Routine>> {
334+
vec![]
335+
}
336+
337+
fn fmaximum_numf_cases() -> Vec<TestCase<op::fmaximum_numf::Routine>> {
338+
vec![]
339+
}
340+
341+
fn fmaximum_num_cases() -> Vec<TestCase<op::fmaximum_num::Routine>> {
342+
vec![]
343+
}
344+
345+
#[cfg(f128_enabled)]
346+
fn fmaximum_numf128_cases() -> Vec<TestCase<op::fmaximum_numf128::Routine>> {
347+
vec![]
348+
}
349+
350+
#[cfg(f16_enabled)]
351+
fn fminf16_cases() -> Vec<TestCase<op::fminf16::Routine>> {
315352
vec![]
316353
}
317354

318355
fn fminf_cases() -> Vec<TestCase<op::fminf::Routine>> {
319356
vec![]
320357
}
321358

359+
fn fmin_cases() -> Vec<TestCase<op::fmin::Routine>> {
360+
vec![]
361+
}
362+
322363
#[cfg(f128_enabled)]
323364
fn fminf128_cases() -> Vec<TestCase<op::fminf128::Routine>> {
324365
vec![]
325366
}
326367

327368
#[cfg(f16_enabled)]
328-
fn fminf16_cases() -> Vec<TestCase<op::fminf16::Routine>> {
369+
fn fminimumf16_cases() -> Vec<TestCase<op::fminimumf16::Routine>> {
370+
vec![]
371+
}
372+
373+
fn fminimumf_cases() -> Vec<TestCase<op::fminimumf::Routine>> {
374+
vec![]
375+
}
376+
377+
fn fminimum_cases() -> Vec<TestCase<op::fminimum::Routine>> {
378+
vec![]
379+
}
380+
381+
#[cfg(f128_enabled)]
382+
fn fminimumf128_cases() -> Vec<TestCase<op::fminimumf128::Routine>> {
383+
vec![]
384+
}
385+
386+
#[cfg(f16_enabled)]
387+
fn fminimum_numf16_cases() -> Vec<TestCase<op::fminimum_numf16::Routine>> {
388+
vec![]
389+
}
390+
391+
fn fminimum_numf_cases() -> Vec<TestCase<op::fminimum_numf::Routine>> {
392+
vec![]
393+
}
394+
395+
fn fminimum_num_cases() -> Vec<TestCase<op::fminimum_num::Routine>> {
396+
vec![]
397+
}
398+
399+
#[cfg(f128_enabled)]
400+
fn fminimum_numf128_cases() -> Vec<TestCase<op::fminimum_numf128::Routine>> {
329401
vec![]
330402
}
331403

crates/libm-test/src/mpfloat.rs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,14 @@ libm_macros::for_each_function! {
148148
floorf,
149149
floorf128,
150150
floorf16,
151+
fmaximum,
152+
fmaximumf,
153+
fmaximumf128,
154+
fmaximumf16,
155+
fminimum,
156+
fminimumf,
157+
fminimumf128,
158+
fminimumf16,
151159
fmod,
152160
fmodf,
153161
fmodf128,
@@ -197,8 +205,10 @@ libm_macros::for_each_function! {
197205
fabs | fabsf => abs,
198206
fdim | fdimf | fdimf16 | fdimf128 => positive_diff,
199207
fma | fmaf | fmaf128 => mul_add,
200-
fmax | fmaxf | fmaxf16 | fmaxf128 => max,
201-
fmin | fminf | fminf16 | fminf128 => min,
208+
fmax | fmaxf | fmaxf16 | fmaxf128 |
209+
fmaximum_num | fmaximum_numf | fmaximum_numf16 | fmaximum_numf128 => max,
210+
fmin | fminf | fminf16 | fminf128 |
211+
fminimum_num | fminimum_numf | fminimum_numf16 | fminimum_numf128 => min,
202212
lgamma | lgammaf => ln_gamma,
203213
log | logf => ln,
204214
log1p | log1pf => ln_1p,
@@ -446,6 +456,46 @@ macro_rules! impl_op_for_ty_all {
446456
}
447457
}
448458

459+
impl MpOp for crate::op::[< fmaximum $suffix >]::Routine {
460+
type MpTy = (MpFloat, MpFloat);
461+
462+
fn new_mp() -> Self::MpTy {
463+
(new_mpfloat::<Self::FTy>(), new_mpfloat::<Self::FTy>())
464+
}
465+
466+
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
467+
this.0.assign(input.0);
468+
this.1.assign(input.1);
469+
let ord = if this.0.is_nan() || this.1.is_nan() {
470+
this.0.assign($fty::NAN);
471+
Ordering::Equal
472+
} else {
473+
this.0.max_round(&this.1, Nearest)
474+
};
475+
prep_retval::<Self::RustRet>(&mut this.0, ord)
476+
}
477+
}
478+
479+
impl MpOp for crate::op::[< fminimum $suffix >]::Routine {
480+
type MpTy = (MpFloat, MpFloat);
481+
482+
fn new_mp() -> Self::MpTy {
483+
(new_mpfloat::<Self::FTy>(), new_mpfloat::<Self::FTy>())
484+
}
485+
486+
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
487+
this.0.assign(input.0);
488+
this.1.assign(input.1);
489+
let ord = if this.0.is_nan() || this.1.is_nan() {
490+
this.0.assign($fty::NAN);
491+
Ordering::Equal
492+
} else {
493+
this.0.min_round(&this.1, Nearest)
494+
};
495+
prep_retval::<Self::RustRet>(&mut this.0, ord)
496+
}
497+
}
498+
449499
// `ldexp` and `scalbn` are the same for binary floating point, so just forward all
450500
// methods.
451501
impl MpOp for crate::op::[<ldexp $suffix>]::Routine {

crates/libm-test/src/precision.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ pub fn default_ulp(ctx: &CheckCtx) -> u32 {
2525
| Bn::Floor
2626
| Bn::Fma
2727
| Bn::Fmax
28+
| Bn::Fmaximum
29+
| Bn::FmaximumNum
2830
| Bn::Fmin
31+
| Bn::Fminimum
32+
| Bn::FminimumNum
2933
| Bn::Fmod
3034
| Bn::Frexp
3135
| Bn::Ilogb

crates/libm-test/tests/compare_built_musl.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,24 @@ libm_macros::for_each_function! {
102102
fmaf128,
103103
fmaxf128,
104104
fmaxf16,
105+
fmaximum,
106+
fmaximum_num,
107+
fmaximum_numf,
108+
fmaximum_numf128,
109+
fmaximum_numf16,
110+
fmaximumf,
111+
fmaximumf128,
112+
fmaximumf16,
105113
fminf128,
106114
fminf16,
115+
fminimum,
116+
fminimum_num,
117+
fminimum_numf,
118+
fminimum_numf128,
119+
fminimum_numf16,
120+
fminimumf,
121+
fminimumf128,
122+
fminimumf16,
107123
fmodf128,
108124
fmodf16,
109125
ldexpf128,

crates/util/src/main.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,24 @@ fn do_eval(basis: &str, op: &str, inputs: &[&str]) {
9999
| fmaf128
100100
| fmaxf128
101101
| fmaxf16
102+
| fmaximum
103+
| fmaximum_num
104+
| fmaximum_numf
105+
| fmaximum_numf128
106+
| fmaximum_numf16
107+
| fmaximumf
108+
| fmaximumf128
109+
| fmaximumf16
102110
| fminf128
103111
| fminf16
112+
| fminimum
113+
| fminimum_num
114+
| fminimum_numf
115+
| fminimum_numf128
116+
| fminimum_numf16
117+
| fminimumf
118+
| fminimumf128
119+
| fminimumf16
104120
| fmodf128
105121
| fmodf16
106122
| ldexpf128

0 commit comments

Comments
 (0)