Skip to content

Commit ce8bf3b

Browse files
committed
implement sqrt for f16 and f128
1 parent 2958f06 commit ce8bf3b

File tree

2 files changed

+45
-15
lines changed

2 files changed

+45
-15
lines changed

src/intrinsics/math.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
2020

2121
match intrinsic_name {
2222
// Operations we can do with soft-floats.
23+
"sqrtf16" => {
24+
let [f] = check_intrinsic_arg_count(args)?;
25+
let f = this.read_scalar(f)?.to_f16()?;
26+
// Sqrt is specified to be fully precise.
27+
let res = math::sqrt(f);
28+
let res = this.adjust_nan(res, &[f]);
29+
this.write_scalar(res, dest)?;
30+
}
2331
"sqrtf32" => {
2432
let [f] = check_intrinsic_arg_count(args)?;
2533
let f = this.read_scalar(f)?.to_f32()?;
@@ -36,6 +44,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
3644
let res = this.adjust_nan(res, &[f]);
3745
this.write_scalar(res, dest)?;
3846
}
47+
"sqrtf128" => {
48+
let [f] = check_intrinsic_arg_count(args)?;
49+
let f = this.read_scalar(f)?.to_f128()?;
50+
// Sqrt is specified to be fully precise.
51+
let res = math::sqrt(f);
52+
let res = this.adjust_nan(res, &[f]);
53+
this.write_scalar(res, dest)?;
54+
}
3955

4056
"fmaf32" => {
4157
let [a, b, c] = check_intrinsic_arg_count(args)?;

tests/pass/float.rs

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,35 @@ fn basic() {
281281
assert_eq!(34.2f64.abs(), 34.2f64);
282282
assert_eq!((-1.0f128).abs(), 1.0f128);
283283
assert_eq!(34.2f128.abs(), 34.2f128);
284+
285+
assert_eq!(64_f16.sqrt(), 8_f16);
286+
assert_eq!(64_f32.sqrt(), 8_f32);
287+
assert_eq!(64_f64.sqrt(), 8_f64);
288+
assert_eq!(64_f128.sqrt(), 8_f128);
289+
assert_eq!(f16::INFINITY.sqrt(), f16::INFINITY);
290+
assert_eq!(f32::INFINITY.sqrt(), f32::INFINITY);
291+
assert_eq!(f64::INFINITY.sqrt(), f64::INFINITY);
292+
assert_eq!(f128::INFINITY.sqrt(), f128::INFINITY);
293+
assert_eq!(0.0_f16.sqrt().total_cmp(&0.0), std::cmp::Ordering::Equal);
294+
assert_eq!(0.0_f32.sqrt().total_cmp(&0.0), std::cmp::Ordering::Equal);
295+
assert_eq!(0.0_f64.sqrt().total_cmp(&0.0), std::cmp::Ordering::Equal);
296+
assert_eq!(0.0_f128.sqrt().total_cmp(&0.0), std::cmp::Ordering::Equal);
297+
assert_eq!((-0.0_f16).sqrt().total_cmp(&-0.0), std::cmp::Ordering::Equal);
298+
assert_eq!((-0.0_f32).sqrt().total_cmp(&-0.0), std::cmp::Ordering::Equal);
299+
assert_eq!((-0.0_f64).sqrt().total_cmp(&-0.0), std::cmp::Ordering::Equal);
300+
assert_eq!((-0.0_f128).sqrt().total_cmp(&-0.0), std::cmp::Ordering::Equal);
301+
assert!((-5.0_f16).sqrt().is_nan());
302+
assert!((-5.0_f32).sqrt().is_nan());
303+
assert!((-5.0_f64).sqrt().is_nan());
304+
assert!((-5.0_f128).sqrt().is_nan());
305+
assert!(f16::NEG_INFINITY.sqrt().is_nan());
306+
assert!(f32::NEG_INFINITY.sqrt().is_nan());
307+
assert!(f64::NEG_INFINITY.sqrt().is_nan());
308+
assert!(f128::NEG_INFINITY.sqrt().is_nan());
309+
assert!(f16::NAN.sqrt().is_nan());
310+
assert!(f32::NAN.sqrt().is_nan());
311+
assert!(f64::NAN.sqrt().is_nan());
312+
assert!(f128::NAN.sqrt().is_nan());
284313
}
285314

286315
/// Test casts from floats to ints and back
@@ -1012,21 +1041,6 @@ pub fn libm() {
10121041
unsafe { ldexp(a, b) }
10131042
}
10141043

1015-
assert_eq!(64_f32.sqrt(), 8_f32);
1016-
assert_eq!(64_f64.sqrt(), 8_f64);
1017-
assert_eq!(f32::INFINITY.sqrt(), f32::INFINITY);
1018-
assert_eq!(f64::INFINITY.sqrt(), f64::INFINITY);
1019-
assert_eq!(0.0_f32.sqrt().total_cmp(&0.0), std::cmp::Ordering::Equal);
1020-
assert_eq!(0.0_f64.sqrt().total_cmp(&0.0), std::cmp::Ordering::Equal);
1021-
assert_eq!((-0.0_f32).sqrt().total_cmp(&-0.0), std::cmp::Ordering::Equal);
1022-
assert_eq!((-0.0_f64).sqrt().total_cmp(&-0.0), std::cmp::Ordering::Equal);
1023-
assert!((-5.0_f32).sqrt().is_nan());
1024-
assert!((-5.0_f64).sqrt().is_nan());
1025-
assert!(f32::NEG_INFINITY.sqrt().is_nan());
1026-
assert!(f64::NEG_INFINITY.sqrt().is_nan());
1027-
assert!(f32::NAN.sqrt().is_nan());
1028-
assert!(f64::NAN.sqrt().is_nan());
1029-
10301044
assert_approx_eq!(25f32.powi(-2), 0.0016f32);
10311045
assert_approx_eq!(23.2f64.powi(2), 538.24f64);
10321046

0 commit comments

Comments
 (0)