Open
Description
Go version
go version go1.21.6 linux/amd64
Output of go env
in your module/workspace:
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/root/.cache/go-build'
GOENV='/root/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/root/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/root/go'
GOPRIVATE=''
GOPROXY='https://goproxy.cn'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.21.6'
GCCGO='/usr/local/bin/gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
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-build734905149=/tmp/go-build -gno-record-gcc-switches'
What did you do?
Use GOSSAFUNC=enc go build qmac.go
or go tool compile -S qmac.go
for its assembly results or see https://godbolt.org/z/9GxzbY4eP.
//qmac.go
package main
func main() {}
type desc struct {
t int
x int
y int
z int
p int
}
func enc(d []byte) []byte {
var buf = d
t, a, b, c, pr := 0, -1, 3, 1, 113
for i := 0; i < len(buf); i++ {
res := process(t, a, b, c, pr)
buf[i] = byte(res.z)
}
return buf
}
//go:noinline
func process(t, a, b, c, pr int) desc {
d := desc{
t: t,
x : a,
y: b,
z: c,
p: pr,
}
//...
return d
}
What did you see happen?
For every loop Go compiler stores the call result into onstack variable main.res
, which is meaningless, as main.res
is only an intermediate result for setting buf[i]
.
I also haven't figured out what autotmp_11
is used for here, why not doing a direct store MOVQ AX, main.res-xx(SP)
instead of MOVQ AX, main..autotmp_11-40(SP)
, MOVQ main..autotmp_11-40(SP), DX
, MOVQ DX, main.res-80(SP)

What did you expect to see?
Compiler can optimize the redundant store operations like following case.
(reduce process
's parameters from 5 to 4)

//qmac2.go
package main
func main() {}
type desc struct {
t int
x int
y int
z int
}
func enc(d []byte) []byte {
var buf = d
t, a, b, c := 0, -1, 3, 1
for i := 0; i < len(buf); i++ {
res := process(t, a, b, c)
buf[i] = byte(res.z)
}
return buf
}
//go:noinline
func process(t, a, b, c int) desc {
d := desc{
t: t,
x : a,
y: b,
z: c,
}
//...
return d
}
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Todo