-
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
math/big: arm64 assembly code for shlVU is incorrect #31084
Comments
Hm. It's only broken on android-arm-wikofever. @eliasnaur, it looks like you're the owner of that builder. Is there anything special about that arm device? It's a Cortex-A53 CPU? |
I don't think it's a special device, other than it being an Android phone. The test also broke on darwin/arm64 (iPhone): https://build.golang.org/log/0b86dd35833a34f28785d335153946ed9a5a3691 which I assume uses an entirely different CPU. |
Indeed, and that appears to be an iPhone 7+. Interesting. |
Here's a smaller test case: https://play.golang.org/p/7OUzcEgoVGk In the playground, and elsewhere, running this code produces the correct result:
On android-arm-wikofever (and presumably darwin/arm64) we get:
That is the fraction is completely wrong. |
The fraction is correct for 1e-164, and then wrong for 1e165. |
Change https://golang.org/cl/169721 mentions this issue: |
This addresses the failures we have seen in #31084. The correct fix is to find the actual bug in the assembly code. Updates #31084. Change-Id: I437780c53d0c4423d742e2e3b650b899ce845372 Reviewed-on: https://go-review.googlesource.com/c/go/+/169721 Run-TryBot: Robert Griesemer <gri@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
I've tracked this down a bit more. Here is a stand-alone test file (to be added to the math/big test files) that exposes the problem: package big
import (
"strings"
"testing"
)
func TestSHLVU(t *testing.T) {
// compute 10^n via 5^n << n
const n = 165
p := nat(nil).expNN(nat{5}, nat{n}, nil)
p = p.shl(p, uint(n)) // <<< this doesn't work using ·shlVU
// p = nat(nil).shl(p, uint(n)) // <<< this works
got := string(p.utoa(10))
want := "1" + strings.Repeat("0", n)
if got != want {
t.Errorf("got %s\nwant %s\n", got, want)
}
} When run with the
When the assembly routine is disabled, the code works fine. When the assembly routine is enabled but the test case is tweaked slightly such that it uses a When fixing this, one should also look into cc: @erifan @josharian who seem to have written some of this code |
Also, the shift==0 case is missing an optimization. If The pure Go code uses the |
It's definitively subtle. The problem doesn't appear for n < 165, at least for |
Sorry, I'll fix this bug. |
The problem is that the loop in the assembler code goes forward through the arrays. It has to go backward. Otherwise the output overwrites the input. The same is true of |
Of course I'm wrong about |
@bradfitz I can't imagine this doesn't fail on all arm64 CPUs, yet I see no arm64 builders on build.golang.org apart from the mobiles. Are they gone or am I blind? |
The code has been written and I will submit it immediately. |
Change https://golang.org/cl/169780 mentions this issue: |
I found that the implementation of shlVU on amd64 does not consider the case where the high byte of z overlaps with the low byte of x, so I also did not consider this point. Do we need to consider this situation? |
We only have to consider word level overlap, not byte level overlap, if that is what you mean. But we do have to consider the case where the high word of z overlaps with the low word of x. I don't see any obvious problem in the amd64 implementation but maybe there is one. |
Byte-overlap should never happen, it's either one or more words, or none - otherwise we'd have a serious bug elsewhere. You can safely assume that all pointers are word-aligned. The assembly code should behave essentially the same as |
Yes I mean Word level overlap. And I can construct an negative case for this situation, which can prove that the current pure Go implementation are defective.
Add this test to file math/big/arith_test.go, and run With the pure Go implementation, we get: --- FAIL: TestShlVUOverlap (0.00s) The current use cases of function shl didn't expose this bug, and as function nat.shl is not a public function, so I wonder if we need to consider this situation when implementing this function or is there some mechanisms that can guarantee this situation never happen? |
|
The code might, but I couldn't tell you those limitations offhand. It'd be good to document them. Once they're documented, we can start fuzzing them using those documented limitations. Since there are multiple implementations, these are good fuzz candidates. (I have started on this.) |
Change https://golang.org/cl/168257 mentions this issue: |
DO NOT MAIL TODO: shrVU too TODO: benchmarks TODO: fuzz for confidence TODO: better commit message When shift == 0, shlVU and shrVU reduce to a memcopy. When z.ptr == x.ptr, it further reduces to a no-op. The pure Go implementation has these optimizations, as of https://go-review.googlesource.com/c/go/+/164967. The arm64 implementation has one of them (see golang#31084 (comment)). We should add both to the amd64 implementation. cc @griesemer Fixes golang#31097 Change-Id: I3979d7c82a63e1840c8191636a8947e8f440af3b
@gopherbot Please open backport issue to 1.13 |
Backport issue(s) opened: #32940 (for 1.13). Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://golang.org/wiki/MinorReleases. |
@erifan Why do you think this should be backported to Go 1.13? Go 1.13 hasn't been released yet, it can't have backports. Did you mean another release? |
Hi @dmitshur , I just hope that this fix can go into Go1.13. This fix was merged before the release date of Go1.12.6, but it did not enter the Go1.12.6. I'm not sure if it will go into Go.1.13, so I raised this request. |
@erifan Since the fix is in I'll close the 1.13 cherry-pick issue since it's not necessary. |
@dmitshur Ok, thanks. |
Excuse me @dmitshur , There's another question. Will there be a Go1.12.7 version before Go1.13? If so, I hope this fix can be ported in Go1.12.7. Or, if there is Go1.12.7, no backport is needed and this fix will be included? Thanks. |
There will be a Go 1.12.7 release soon (we aim to make minor releases monthly). We can consider cherry-picking this fix to 1.12 if it meets the backporting criteria (described here). If it doesn't, then it'll be available starting with 1.13. |
@erifan According to the original issue, this breakage started with commit e4ba400. That commit isn't a part of 1.12. So does this problem exist in 1.12? |
@dmitshur In Go, the breakage started from commit e4ba400, but for user code, the affected version may be earlier than 1.12, and there is currently no release version that fixes this issue. The user of Project https://github.com/shopspring/decimal complained to me about this issue. Since it is a library function, users will use it frequently, so I think this is a security issue. If possible, please port it to Go1.12.7, thank you. |
@dmitshur Yeah, I'd like to, thanks. |
Change https://golang.org/cl/185041 mentions this issue: |
…ion of shlVU on arm64 For the case where the addresses of parameter z and x of the function shlVU overlap and the address of z is greater than x, x (input value) can be polluted during the calculation when the high words of x are overlapped with the low words of z (output value). Updates #31084 Fixes #32940 Change-Id: I9bb0266a1d7856b8faa9a9b1975d6f57dece0479 Reviewed-on: https://go-review.googlesource.com/c/go/+/169780 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com> (cherry picked from commit 503e6cc) Reviewed-on: https://go-review.googlesource.com/c/go/+/185041 Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
This is a minor release of Go that does not include any changes that affect Terraform's behavior. This does include a fix for golang/go#31084 that could potentially affect HCL arithmetic (via math/big) on aarch64, but we do not currently build Terraform for aarch64 so it cannot have affected any previous releases.
This is a minor release of Go that does not include any changes that affect Terraform's behavior. This does include a fix for golang/go#31084 that could potentially affect HCL arithmetic (via math/big) on aarch64, but we do not currently build Terraform for aarch64 so it cannot have affected any previous releases.
The
TestFloat64SpecialCases
test inmath/big
(ratconv_test.go) is currently broken on the android/arm64 builder, with log:https://build.golang.org/log/fbc581637a0375532f0d819ae67bc9b9abbe8ba9
Breakage started at e4ba400 (math/big: accept non-decimal floats with Rat.SetString).
cc @griesemer
The text was updated successfully, but these errors were encountered: