-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Should std::{f32,f64}::NAN be a QNAN or SNAN ? #52897
Comments
Note that "on MIPS at least" is imprecise: which bit pattern is considered quiet and which pattern is considered signaling depends on the used MIPS version and configuration. See #46246 for more info. |
@est31 indeed. #52666 suggests leaving the current mips targets for the "older" mips versions (r5 and older), and to add a new targets (e.g. MIPS in the issue refers to |
Why? Considering how LLVM behaves (and the differences in how hardware handle payloads, too!), I can't think of any (edit: portable) use case that can reliably use any particular |
The guarantees provided by |
In Debian, we hit what I believe to be the issue at hand. The issue surfaced in rust-num/num-traits#151 where the tests worked before and don't work any longer now in mipsel and mips64el. |
@silwol I'd expect that minnum/maxnum use libcall legalization on mips, so you're likely seeing libm behavior here. Can you check whether that's the case? Per the C standard, I believe fmin/fmax should be treating SNaN the same as QNaN (contrary to IEEE754). |
@nikic I hope I checked this the right way. If not, please give me a hint how / where to try next. The important information here is that it's not the Here is what I tried:
This behaves exactly the same on Debian In contrast, the following behaved the same on these architectures with General information on my mipsel VM:
Trying with latest stable
Trying with latest known-to-work stable rustc:
I'm not very familiar with compiler internals, so please let me know if that might be a different problem from this one, then I'll move it to a new issue. |
@silwol which mips version does your cpu have? E.g. what does running |
For checking if the error is reproducible, I started a qemu mipsel VM with
Regarding the Debian infrastructure, I don't have direct access to these machines. The failing test logs can be found on https://buildd.debian.org/status/package.php?p=rust-num-traits from where you can follow the link to the machine information in the Buildd column. There you have a "Build machine info" entry somewhere in the head, showing a list of links to the details of each machine. |
I just looked up the information about the physical machines that built the project. They're all listed with Processor: Rhino Labs UTM8. There are machines available with Processor: LS3A-RS780-1w (Quad Core Loongson 3A) and Processor: Lemote 3A ITX-A1101 (Quad Core Loongson 3A), but I don't know if there is any way to assign builds explicitly to a specific machine type. |
The
Which is clearly not the case here. f32::max itself is only a wrapper of the The docs of that LLVM intrinsic say:
So this promise seems to be violated as well. However, this does not imply a bug in llvm just yet, as we provide some intrinsics to llvm. It might be the intrinsics that are wrong. The Rust based libm implementation has this fmaxf code. So maybe the bug lurks there? The code looks alright though. |
Thanks @est31 for the hints. |
@silwol yeah there is a fundamental difference between older MIPS targets and newer MIPS targets in that the signaling bit is opposite to IEEE 754-2008 vs follows the standard. But even older MIPS targets follow IEEE 754-1985 which clearly specifies the bit patterns of NaNs (it only doesn't specify the bit pattern distinction between qNaN and sNaN). @silwol if you have access to a MIPS machine you could try finding the nightly that caused the regression using cargo-bisect-rustc. Either way, I think you should file a proper issue for your bug report. |
IEEE 754-2008 is obsolete. You should follow IEEE 754-2019, where the poorly designed minNum and maxNum operations (as being non-associative) have been replaced by other operations, which handle qNaN and sNaN in the same way (except for the signaled invalid operation exception in case of sNaN). |
Right now, whether they are a QNAN or an SNAN depends on the architecture. Currently, they are an SNAN on MIPS (EDIT: r5 and older) at least, and a QNAN on most others.
It probably makes sense to offer consistent behavior here independently of whether LLVM preservers payloads, signaling/quietness, etc.
cc @rkruppe @draganmladjenovic
The text was updated successfully, but these errors were encountered: