-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Description
What version of Go are you using (go version)?
$ go version go version go1.20.5 linux/amd64
Does this issue reproduce with the latest release?
Yes, I can reproduce in go1.20.7 linux/amd64
What operating system and processor architecture are you using (go env)?
go env Output
$ go env GO111MODULE="auto" GOARCH="amd64" GOBIN="" GOCACHE="xxx/.cache/go-build" GOENV="xxx/.config/go/env" GOEXE="" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="xxx/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="xxx/go" GOPRIVATE="" GOPROXY="https://goproxy.cn,direct" GOROOT="xxx/golang/go1.20.5" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="xxx/golang/go1.20.5/pkg/tool/linux_amd64" GOVCS="" GOVERSION="go1.20.5" GCCGO="gccgo" GOAMD64="v1" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="" GOWORK="" CGO_CFLAGS="-O2 -g" CGO_CPPFLAGS="" CGO_CXXFLAGS="-O2 -g" CGO_FFLAGS="-O2 -g" CGO_LDFLAGS="-O2 -g" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build2743047067=/tmp/go-build -gno-record-gcc-switches"
What did you do?
I use go1.20.5 to compile the following code:
package main
func use(...interface{}) {
}
func main() {
testCases := [...][][]int{
{{42}},
{{1, 2}},
{{3, 4, 5}},
{{}},
{{1, 2}, {3, 4, 5}, {}, {7}},
}
for _, testCase := range testCases {
use(testCase)
}
}In the generated SSA and assembly code, I notice that the Go compiler generates some instructions that store a stack pointer(point to the stack-allocated array) into a global slice header.
Just like the assembly code below, the MOV instruction at 0x4585bf stores a stack pointer into a global object:
0x458589 48c744240800000000 MOVQ $0x0, 0x8(SP)
0x458592 48c74424082a000000 MOVQ $0x2a, 0x8(SP)
testCases := [...][][]int{
0x45859b 48c705c28e060001000000 MOVQ $0x1, 0x68ec2(IP)
0x4585a6 48c705bf8e060001000000 MOVQ $0x1, 0x68ebf(IP)
0x4585b1 833d988d090000 CMPL $0x0, runtime.writeBarrier(SB)
0x4585b8 750e JNE 0x4585c8
0x4585ba 488d442408 LEAQ 0x8(SP), AX
0x4585bf 4889059a8e0600 MOVQ AX, 0x68e9a(IP)
0x4585c6 eb11 JMP 0x4585d9
0x4585c8 488d3d918e0600 LEAQ 0x68e91(IP), DI
0x4585cf 488d442408 LEAQ 0x8(SP), AX
0x4585d4 e8e7cfffff CALL runtime.gcWriteBarrier(SB)I have read the comments in slicelit, but I didn't find any operations that can generate such stores. As far as I know, pointers to stack objects cannot be stored in global objects. So is this a compiler bug? Or the Go compiler does this on purpose to achieve some optimization I don't know yet?
note: this is originally posted on golang-nuts
Thanks
What did you expect to see?
The stack pointer is not stored into any global object.
What did you see instead?
The stack pointer is stored into a global object.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status