-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
cmd/compile: inconsistent signaling NaN behavior on mips64le #37455
Comments
Note that this behavior also appears on the other rtrk builders (32/64 bit, and big/little endian). |
I think it should generate a quiet NaN. The MIPS manual said
Also
|
According to http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1011.htm:
but:
So the behavior on the |
Could this be due to a difference in the default kernel or |
Is it possible the mips rtrk builders may be using a soft-float implementation? https://golang.org/src/runtime/softfloat64.go converts all NaN to signalling NaN as that is the only NaN bit pattern returned for all ops.
It seems like nan64 and nan32 should be changed to a quiet NaN, i.e.
Or just write out the explicit bit pattern for clarity like in the math package https://golang.org/src/math/bits.go?s=671:689#L21 That of course doesn't explain the C results unless they also have the same issue in their soft-float implementation. |
You're right that the soft float implementation should probably be fixed. But as you noted, that isn't the rtrk problem. |
I think the softfloat in runtime/softfloat64.go is only used by the arm/GOARM=5 port. |
The softfloat code is used on GOARM=5, or GOMIPS=softfloat, or compiler's |
+0 is a red herring. The same bug occurs with +7. Who is the owner of the rtrk builders? Can one of those people take a look? (Maybe it is @milanknezevic ?) |
Change https://golang.org/cl/221433 mentions this issue: |
@randall77
If I recall correctly Linux kernels prior 4.5 are unaware of NaN2008 encoding and will happily run [1] https://sourceware.org/binutils/docs/as/MIPS-NaN-Encodings.html |
Interesting. So we just need to set the EF_MIPS_NAN2008 bit in the elf header? I can't seem to make that work. The gcc install can't seem to handle
And when I change the Go toolchain to set that bit in executables with this patch:
I get the following error:
|
I also tried this patch to set the control register bit on startup. It compiled and ran, but somehow it didn't fix the underlying problem.
(I also tried all the other FCRs. Why are there 32 control registers?) |
@randall77 I believe that other FCSR registers are RW or RO views of FCSR31. You are probably hitting [1]. You technically have to assume that "legacy" behavior is the correct one and not trying to fix it. You might be able to force nan2008 back to legacy. FPU hardware may or may not support this. Maybe the kernel on mengzhuo builder is older than 4.5 or is running in "lax mode" (can't remember kernel command line argument used for that edit: [2]) that doesn't enforce nan2008/legacy consistency, so you get nan2008 fpu behavior while running "legacy" binary. As for gcc -mnan2008 requires a separate sysroot and rebuild of whole distribution. [1] https://github.com/torvalds/linux/blob/2f4c53349961c8ca480193e47da4d44fdb8335a8/arch/mips/kernel/elf.c#L161 |
FYI: Most new MIPS system (e.g. Loongson-3A4000, Ingeinc X1830) implemented NAN2008 mode only while older hardware (e.g. Loongson-3A3000, Ingeinc JZ4780, MediaTek MT7620) are legacy only. In theory, some systems should have configurable NAN, but I know none of them. Due to interlink issue caused by NAN2008 binary, most of the users are using NAN2008 hardware with legacy distro and force In my point of view, we'd better keep Golang's |
This Loongson box runs on Linux 4.19.
|
Update #37455 Change-Id: Ieac0823aa398d73187c009037be15ba34c84f3d9 Reviewed-on: https://go-review.googlesource.com/c/go/+/221433 Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
Oh well. At least we now understand what is going on. |
Compile and run the following C program:
On the linux-mips64le-mengzhuo builders, it prints
On the linux-mips64le-rtrk builders, it prints
Note that on the mengzhuo builder, the quiet bit gets set, whereas on the rtrk builder it does not.
This seems like a strange inconsistency. The assembly code for
add0
is the same on both platforms.It seems strange that the rtrk builder doesn't convert the NaN from signaling to quiet.
add0
quiets the NaN for all the other Go platforms we support (amd64, powerpc, etc.). There are also strange inconsistencies with how it handles float32 <-> float64 conversions of signaling NaNs, which is how I first noticed this (#36399).Is this expected behavor? Is this allowed by the spec? Might it be a bug in the rtrk builder? Is there some floating-point-signal-interrupt-control-word thingy we might need to set?
@mengzhuo @milanknezevic
The text was updated successfully, but these errors were encountered: