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

Commit e22badf

Browse files
committed
update
1 parent 1c07ae0 commit e22badf

File tree

2 files changed

+41
-38
lines changed

2 files changed

+41
-38
lines changed

crates/libm-test/src/precision.rs

+2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ pub fn default_ulp(ctx: &CheckCtx) -> u32 {
4747

4848
// Operations that aren't required to be exact, but our implementations are.
4949
Bn::Cbrt => 0,
50+
Bn::Hypot if ctx.fn_ident == Id::Hypot => 0,
5051

5152
// Bessel functions have large inaccuracies.
5253
Bn::J0 | Bn::J1 | Bn::Y0 | Bn::Y1 | Bn::Jn | Bn::Yn => 8_000_000,
@@ -99,6 +100,7 @@ pub fn default_ulp(ctx: &CheckCtx) -> u32 {
99100
Id::Cbrt => ulp = 2,
100101
// FIXME(#401): musl has an incorrect result here.
101102
Id::Fdim => ulp = 2,
103+
Id::Hypot => ulp = 1,
102104
Id::Sincosf => ulp = 500,
103105
Id::Tgamma => ulp = 20,
104106
_ => (),

src/math/hypot.rs

+39-38
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,18 @@ fn cr_hypot(mut x: f64, mut y: f64) -> f64 {
4141
let wx: u64 = xi << 1;
4242
let wy: u64 = yi << 1;
4343
let wm: u64 = emsk << 1;
44-
let ninf: i32 = ((wx == wm) ^ (wy == wm)) as i32;
45-
let nqnn: i32 = (((wx >> 52) == 0xfff) ^ ((wy >> 52) == 0xfff)) as i32;
46-
/* ninf is 1 when only one of x and y is +/-Inf
47-
nqnn is 1 when only one of x and y is qNaN
48-
IEEE 754 says that hypot(+/-Inf,qNaN)=hypot(qNaN,+/-Inf)=+Inf. */
49-
if ninf != 0 && nqnn != 0 {
44+
45+
let one_inf = (wx == wm) ^ (wy == wm);
46+
let one_nan = x.is_nan() ^ y.is_nan();
47+
48+
// let nqnn: i32 = (((wx >> 52) == 0xfff) ^ ((wy >> 52) == 0xfff)) as i32;
49+
// /* ninf is 1 when only one of x and y is +/-Inf
50+
// nqnn is 1 when only one of x and y is qNaN
51+
// IEEE 754 says that hypot(+/-Inf,qNaN)=hypot(qNaN,+/-Inf)=+Inf. */
52+
if one_inf && one_nan {
5053
return f64::INFINITY;
5154
}
52-
return x + y; /* inf, nan */
55+
return x + y; /* inf, sNaN */
5356
}
5457

5558
let u: f64 = x.max(y);
@@ -88,7 +91,7 @@ fn cr_hypot(mut x: f64, mut y: f64) -> f64 {
8891
let de: u64 = xd.wrapping_sub(yd);
8992
if de > (27_u64 << 52) {
9093
cold_path();
91-
return __builtin_fma(hf64!("0x1p-27"), v, u);
94+
return fmaf64(hf64!("0x1p-27"), v, u);
9295
}
9396

9497
let off: i64 = (0x3ff_i64 << 52) - (xd & emsk) as i64;
@@ -97,25 +100,25 @@ fn cr_hypot(mut x: f64, mut y: f64) -> f64 {
97100
x = f64::from_bits(xd);
98101
y = f64::from_bits(yd);
99102
let x2: f64 = x * x;
100-
let dx2: f64 = __builtin_fma(x, x, -x2);
103+
let dx2: f64 = fmaf64(x, x, -x2);
101104
let y2: f64 = y * y;
102-
let dy2: f64 = __builtin_fma(y, y, -y2);
105+
let dy2: f64 = fmaf64(y, y, -y2);
103106
let r2: f64 = x2 + y2;
104107
let ir2: f64 = 0.5 / r2;
105108
let dr2: f64 = ((x2 - r2) + y2) + (dx2 + dy2);
106109
let mut th: f64 = sqrt(r2);
107110
let rsqrt: f64 = th * ir2;
108-
let dz: f64 = dr2 - __builtin_fma(th, th, -r2);
111+
let dz: f64 = dr2 - fmaf64(th, th, -r2);
109112
let mut tl: f64 = rsqrt * dz;
110113
th = fasttwosum(th, tl, &mut tl);
111114
let mut thd: u64 = th.to_bits();
112-
let tld = __builtin_fabs(tl).to_bits();
115+
let tld = tl.abs().to_bits();
113116
ex = thd;
114117
ey = tld;
115118
ex &= 0x7ff_u64 << 52;
116119
let aidr: u64 = ey + (0x3fe_u64 << 52) - ex;
117120
let mid: u64 = (aidr.wrapping_sub(0x3c90000000000000) + 16) >> 5;
118-
if mid == 0 || aidr < 0x39b0000000000000_u64 || aidr > 0x3c9fffffffffff80_u64 {
121+
if mid == 0 || !(0x39b0000000000000_u64..=0x3c9fffffffffff80_u64).contains(&aidr) {
119122
cold_path();
120123
thd = as_hypot_hard(x, y, flag).to_bits();
121124
}
@@ -164,10 +167,11 @@ fn as_hypot_hard(x: f64, y: f64, flag: FExcept) -> f64 {
164167
rm |= 1u64 << 52;
165168

166169
for _ in 0..3 {
167-
if __builtin_expect(rm == 1u64 << 52, true) {
170+
if rm == 1u64 << 52 {
168171
rm = u64::MAX >> 11;
169172
re -= 1;
170173
} else {
174+
cold_path();
171175
rm -= 1;
172176
}
173177
}
@@ -177,10 +181,11 @@ fn as_hypot_hard(x: f64, y: f64, flag: FExcept) -> f64 {
177181
let de: i32 = be - le;
178182
let mut ls: i32 = bs - de;
179183

180-
if __builtin_expect(ls >= 0, true) {
184+
if ls >= 0 {
181185
lm <<= ls;
182186
m2 += lm.wrapping_mul(lm);
183187
} else {
188+
cold_path();
184189
let lm2: u128 = (lm as u128) * (lm as u128);
185190
ls *= 2;
186191
m2 += (lm2 >> -ls) as u64;
@@ -203,19 +208,19 @@ fn as_hypot_hard(x: f64, y: f64, flag: FExcept) -> f64 {
203208

204209
if d == 0 {
205210
set_flags(flag);
206-
} else {
207-
if __builtin_expect(op == om, true) {
208-
let tm: u64 = (rm << k) - (1 << (k - (rm <= (1u64 << 53)) as i32));
209-
d = m2 as i64 - (tm.wrapping_mul(tm)) as i64;
211+
} else if op == om {
212+
let tm: u64 = (rm << k) - (1 << (k - (rm <= (1u64 << 53)) as i32));
213+
d = m2 as i64 - (tm.wrapping_mul(tm)) as i64;
210214

211-
if __builtin_expect(d != 0, true) {
212-
rm = rm.wrapping_add((d >> 63) as u64);
213-
} else {
214-
rm -= rm & 1;
215-
}
215+
if d == 0 {
216+
cold_path();
217+
rm -= rm & 1;
216218
} else {
217-
rm -= ((op == 1.0) as u64) << (rm > (1u64 << 53)) as u32;
219+
rm = rm.wrapping_add((d >> 63) as u64);
218220
}
221+
} else {
222+
cold_path();
223+
rm -= ((op == 1.0) as u64) << (rm > (1u64 << 53)) as u32;
219224
}
220225

221226
if rm >= (1u64 << 53) {
@@ -282,20 +287,16 @@ fn as_hypot_denorm(mut a: u64, mut b: u64) -> f64 {
282287
f64::from_bits(xi)
283288
}
284289

285-
fn __builtin_expect<T>(v: T, _exp: T) -> T {
286-
v
287-
}
288-
289-
fn __builtin_fabs(x: f64) -> f64 {
290-
x.abs()
291-
}
292-
293-
fn __builtin_copysign(x: f64, y: f64) -> f64 {
294-
x.copysign(y)
295-
}
290+
fn fmaf64(x: f64, y: f64, z: f64) -> f64 {
291+
#[cfg(intrinsics_enabled)]
292+
{
293+
return unsafe { core::intrinsics::fmaf64(x, y, z) };
294+
}
296295

297-
fn __builtin_fma(x: f64, y: f64, z: f64) -> f64 {
298-
unsafe { core::intrinsics::fmaf64(x, y, z) }
296+
#[cfg(not(intrinsics_enabled))]
297+
{
298+
return super::fma(x, y, z);
299+
}
299300
}
300301

301302
type FExcept = u32;

0 commit comments

Comments
 (0)