-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
Description
Our documentation says that max(SNaN, 0.0) should return 0.0. On x86_64, this is indeed what happens. However, on aarch64, we get a QNaN as a result instead. On Android, the reported result for this test is:
F32::from(F32::nan(Sign::Pos, NaNKind::Signaling, 1).as_f32().max(0.0)) = 0x7fc00001 (NaN: Pos, Quiet, payload = 0x1)
It seems that LLVM never actually correctly implemented the promise that "if exactly one argument is NaN, the other argument is returned". Recently things got a lot more messy (see llvm/llvm-project#170082 and also this discussion), but apparently things were already broken before this recent chaos.
Also, since Rust 1.91 optimizations seem to fold max(SNaN, x) into NaN.
It is also worth noting that glibc fmin/fmax were deliberately patched so that SNaN inputs produce NaN results. (However, not all libc do that; the C standard generally says very little about SNaN.)
So it might just be worth dropping that promise and allowing NaN outputs when there is an SNaN input (but also continue to allow returning the other input).
Cc @tgross35 @valadaptive @nikic @workingjubilee @rust-lang/libs-api