-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/compile: -m flag unexpectedly affects compilation output #22378
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
Comments
\cc @randall77 @cherrymui |
I cannot reproduce it, with both Go 1.9 and tip (006bc57), at least on darwin/amd64. Then binaries generated with
@huguesb, which version of Go, and what GOARCH/GOOS are you using? |
@cherrymui I'm on darwin/amd64. This issue is reliably reproducible with CL72490 applied on top of tip (
|
Ok, it seems there is something racy here, which may or may not be related to your CL. With your CL applied, I run Without concurrent compilation, it still generates identical binaries:
|
@cherrymui thanks for taking a look, I did not think of concurrent compilation. Is there an easy way of building the compiler with the race detector enabled? The naive |
I'm actually not sure. I guess |
I tried building a race-enabled compiler with |
I finally figured out the problem: there was a subtle bug in my change which resulted in references to captured variables inside the inlined body using the same node as inside the regular closure body, instead of being substituted with local temporaries in every inlined location. I'm guessing the SSA phase either modifies the AST in-place or uses AST nodes as map keys, which leads to the observed issue when the regular closure body and a function with the inlined closure are compiled concurrently. Is this documented somewhere? |
Yes, order and walk mutate the function's AST.
I don't think so. The general rule is the goroutine that's compiling a function has exclusive ownership over that function during concurrent compilation. If you need to do interprocedural stuff, you should do it before concurrent compilation. Some stuff is safe to inspect externally. For example, the ONAME Nodes representing the function name and parameters are safe for basic use, but these basically become read-only once the early analysis phases are done. |
That's not the issue here though. Order and walk are not executed concurrently at this point, only the SSA phase is. |
Yes, there are a few in cmd/compile/internal/gc/ssa.go, also plive.go. |
I am currently working on some changes to the inliner for #15561, the current state of my work is https://go-review.googlesource.com/c/go/+/72490
While testing my changes, I noticed a very odd behavior, namely that code miscompiled when my inliner changes where triggered, was compiled correctly when passing the
-m
flag.The following code is reduced reproducer from a failure observed in
generateTrace
fromcmd/trace/trace.go
Diffing a disassembly of this program, compiled with
- l -l
and-l -l -m
respectively, gives the following:The only other reference to the
0x20(SP)
slot is, in both cases, the return value of the mapaccess call inside the inlined closure body :I realize that there is probably something wrong with my inliner changes. However, I'm submitting this bug nonetheless because I find it very surprising that the
-m
flag somehow fixes this issue, even though it should only affect compiler logs and not the resulting binary. This seems like it might be a latent issue in the compiler that would be worth fixing.I have manually audited all locations that read
Debug['m']
inside the compiler and didn't notice anything suspicious/side-effecty so I'm pretty stumped at this point and could use another pair of eyes.The text was updated successfully, but these errors were encountered: