Skip to content

Commit 2a46cba

Browse files
committed
Don't assume all NaNs being type-converted are quiet NaNs
When truncating floating point types, we detect whether the original value was any kind of NaN, but reconstruct the destination value with the qNaN bit always set - meaning any signalling NaNs get lost. This patch explicitly includes the source qNaN bit as part of the data which is copied over.
1 parent cd0f202 commit 2a46cba

File tree

1 file changed

+2
-3
lines changed

1 file changed

+2
-3
lines changed

compiler-builtins/src/float/trunc.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ where
2424
let round_mask = (src_one << (F::SIG_BITS - R::SIG_BITS)) - src_one;
2525
let halfway = src_one << (F::SIG_BITS - R::SIG_BITS - 1);
2626
let src_qnan = src_one << (F::SIG_BITS - 1);
27-
let src_nan_code = src_qnan - src_one;
27+
let src_nan_code = (src_qnan << 1) - src_one;
2828

2929
let dst_zero = R::Int::ZERO;
3030
let dst_one = R::Int::ONE;
@@ -38,7 +38,7 @@ where
3838
let overflow: F::Int = overflow_exponent << F::SIG_BITS;
3939

4040
let dst_qnan = R::Int::ONE << (R::SIG_BITS - 1);
41-
let dst_nan_code = dst_qnan - dst_one;
41+
let dst_nan_code = (dst_qnan << 1) - dst_one;
4242

4343
let sig_bits_delta = F::SIG_BITS - R::SIG_BITS;
4444
// Break a into a sign and representation of the absolute value.
@@ -71,7 +71,6 @@ where
7171
// Cast before shifting to prevent overflow.
7272
let dst_inf_exp: R::Int = dst_inf_exp.cast();
7373
abs_result = dst_inf_exp << R::SIG_BITS;
74-
abs_result |= dst_qnan;
7574
abs_result |= dst_nan_code & ((a_abs & src_nan_code) >> (F::SIG_BITS - R::SIG_BITS)).cast();
7675
} else if a_abs >= overflow {
7776
// a overflows to infinity.

0 commit comments

Comments
 (0)