Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions builtins-test/tests/addsub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,25 @@ macro_rules! float_sum {
);
}
});

// Quiet sNaN by setting the top significand bit. `sub(x, nan)`
// flips that sign because sub is add with b's sign bit inverted.
let one = <$f as Float>::ONE;
for input in [
<$f as Float>::SNAN,
<$f as Float>::NAN,
<$f as Float>::NEG_SNAN,
<$f as Float>::NEG_NAN,
] {
let expected =
<$f>::from_bits(input.to_bits() | <$f as Float>::SIG_TOP_BIT);
assert_eq!($fn_add(input, one).to_bits(), expected.to_bits());
assert_eq!($fn_add(one, input).to_bits(), expected.to_bits());
assert_eq!($fn_sub(input, one).to_bits(), expected.to_bits());
let flipped =
<$f>::from_bits(expected.to_bits() ^ <$f as Float>::SIGN_MASK);
assert_eq!($fn_sub(one, input).to_bits(), flipped.to_bits());
Comment on lines +112 to +128

@tgross35 tgross35 Sep 2, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May as well check the entire matrix I suppose:

let qnan = <$f>::NAN;
let snan = <$f>::SNAN;
let qsnan = <$f>::QSNAN;
let neg_qnan = <$f>::NEG_NAN;
let neg_snan = <$f>::NEG_SNAN;
let neg_qsnan = <$f>::NEG_QSNAN;
let one = <$f>::ONE;

let nan_cases = [
    (qnan, qnan, qnan),
    (qnan, snan, qnan),
    (qnan, neg_qnan, qnan),
    (qnan, neg_snan, qnan),
    (qnan, one, qnan),

    (snan, qnan, qsnan),
    (snan, snan, qsnan),
    (snan, neg_qnan, qsnan),
    (snan, neg_snan, qsnan),
    (snan, one, qsnan),

    (neg_qnan, qnan, neg_qnan),
    (neg_qnan, snan, neg_qnan),
    (neg_qnan, neg_qnan, neg_qnan),
    (neg_qnan, neg_snan, neg_qnan),
    (neg_qnan, one, neg_qnan),

    (neg_snan, qnan, neg_qsnan),
    (neg_snan, snan, neg_qsnan),
    (neg_snan, neg_qnan, neg_qsnan),
    (neg_snan, neg_snan, neg_qsnan),
    (neg_snan, one, neg_qsnan),
];

for (x, y, expected) in add_nan_cases {
    // ...
}

for (x, y, expected) in sub_cases {
    // ...
}

QSNAN doesn't exist yet, adding it in #1314

View changes since the review

Comment on lines +121 to +128

@tgross35 tgross35 Sep 2, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use assert_biteq!, #1314 makes that possible

View changes since the review

}
}
)*
}
Expand Down
4 changes: 2 additions & 2 deletions compiler-builtins/src/float/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ where
if a_abs.wrapping_sub(one) >= inf_rep - one || b_abs.wrapping_sub(one) >= inf_rep - one {
// NaN + anything = qNaN
if a_abs > inf_rep {
return F::from_bits(a_abs | quiet_bit);
return F::from_bits(a_rep | quiet_bit);
}
// anything + NaN = qNaN
if b_abs > inf_rep {
return F::from_bits(b_abs | quiet_bit);
return F::from_bits(b_rep | quiet_bit);
}

if a_abs == inf_rep {
Expand Down
Loading