Skip to content

cmd/compile: GOEXPERIMENT=runtimefreegc go build does not work if ./make.bash was built without #79631

@yukatan1701

Description

@yukatan1701

Go version

go version go1.27-devel_24ec7d2120 Fri May 22 20:16:59 2026 -0700 linux/amd64

Output of go env in your module/workspace:

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/yukatan/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/yukatan/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1451256312=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/home/yukatan/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPACKAGESDRIVER=''
GOPATH='/home/yukatan/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/yukatan/gerrit/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/yukatan/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/yukatan/gerrit/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.27-devel_24ec7d2120 Fri May 22 20:16:59 2026 -0700'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

Consider the following example:

// main.go

package main

func main() {
	const N = 10000
	a := make([]int, 0)
	for i := 0; i < N; i++ {
		a = append(a, i)
	}
}

I compiled this one with the GOEXPERIMENT=runtimefreegc enabled:

$ GOEXPERIMENT=runtimefreegc go build -gcflags='-S' -o /dev/null ./main.go

What did you see happen?

Nothing happened, no calls to runtime.growsliceNoAlias were generated:

main.main STEXT size=174 align=0x0 args=0x0 locals=0x78 funcid=0x0
	0x0000 00000 (/home/yukatan/freegc/main.go:5)	TEXT	main.main(SB), ABIInternal, $120-0
	0x0000 00000 (/home/yukatan/freegc/main.go:5)	CMPQ	SP, 16(R14)
	0x0004 00004 (/home/yukatan/freegc/main.go:5)	PCDATA	$0, $-2
	0x0004 00004 (/home/yukatan/freegc/main.go:5)	JLS	164
	0x000a 00010 (/home/yukatan/freegc/main.go:5)	PCDATA	$0, $-1
	0x000a 00010 (/home/yukatan/freegc/main.go:5)	PUSHQ	BP
	0x000b 00011 (/home/yukatan/freegc/main.go:5)	MOVQ	SP, BP
	0x000e 00014 (/home/yukatan/freegc/main.go:5)	SUBQ	$112, SP
	0x0012 00018 (/home/yukatan/freegc/main.go:5)	FUNCDATA	$0, gclocals·g5+hNtRBP6YXNjfog7aZjQ==(SB)
	0x0012 00018 (/home/yukatan/freegc/main.go:5)	FUNCDATA	$1, gclocals·g5+hNtRBP6YXNjfog7aZjQ==(SB)
	0x0012 00018 (/home/yukatan/freegc/main.go:8)	XORL	DX, DX
	0x0014 00020 (/home/yukatan/freegc/main.go:8)	LEAQ	main..autotmp_2+112(SP), R8
	0x0019 00025 (/home/yukatan/freegc/main.go:8)	XORL	R9, R9
	0x001c 00028 (/home/yukatan/freegc/main.go:8)	XORL	AX, AX
	0x001e 00030 (/home/yukatan/freegc/main.go:8)	XORL	CX, CX
	0x0020 00032 (/home/yukatan/freegc/main.go:8)	JMP	45
	0x0022 00034 (/home/yukatan/freegc/main.go:9)	MOVQ	DX, -8(R8)(BX*8)
	0x0027 00039 (/home/yukatan/freegc/main.go:8)	INCQ	DX
	0x002a 00042 (/home/yukatan/freegc/main.go:8)	MOVQ	BX, CX
	0x002d 00045 (/home/yukatan/freegc/main.go:8)	CMPQ	DX, $10000
	0x0034 00052 (/home/yukatan/freegc/main.go:8)	JGE	158
	0x0036 00054 (/home/yukatan/freegc/main.go:9)	LEAQ	1(CX), BX
	0x003a 00058 (/home/yukatan/freegc/main.go:9)	CMPQ	AX, BX
	0x003d 00061 (/home/yukatan/freegc/main.go:9)	JCC	34
	0x003f 00063 (/home/yukatan/freegc/main.go:8)	MOVQ	DX, main.i+72(SP)
	0x0044 00068 (/home/yukatan/freegc/main.go:8)	MOVB	R9B, main..autotmp_8+71(SP)
	0x0049 00073 (/home/yukatan/freegc/main.go:9)	CMPQ	BX, $4
	0x004d 00077 (/home/yukatan/freegc/main.go:9)	JGT	116
	0x004f 00079 (/home/yukatan/freegc/main.go:8)	TESTB	R9B, R9B
	0x0052 00082 (/home/yukatan/freegc/main.go:9)	JNE	116
	0x0054 00084 (/home/yukatan/freegc/main.go:9)	TESTQ	CX, CX
	0x0057 00087 (/home/yukatan/freegc/main.go:9)	JNE	116
	0x0059 00089 (/home/yukatan/freegc/main.go:9)	LEAQ	main..autotmp_3+80(SP), R8
	0x005e 00094 (/home/yukatan/freegc/main.go:9)	MOVUPS	X15, (R8)
	0x0062 00098 (/home/yukatan/freegc/main.go:9)	MOVUPS	X15, 16(R8)
	0x0067 00103 (/home/yukatan/freegc/main.go:9)	MOVL	$4, AX
	0x006c 00108 (/home/yukatan/freegc/main.go:9)	MOVL	$1, R9
	0x0072 00114 (/home/yukatan/freegc/main.go:9)	JMP	34
	0x0074 00116 (/home/yukatan/freegc/main.go:9)	MOVQ	AX, CX
	0x0077 00119 (/home/yukatan/freegc/main.go:9)	MOVL	$1, DI
	0x007c 00124 (/home/yukatan/freegc/main.go:9)	LEAQ	type:int(SB), SI
	0x0083 00131 (/home/yukatan/freegc/main.go:9)	MOVQ	R8, AX
	0x0086 00134 (/home/yukatan/freegc/main.go:9)	PCDATA	$1, $0
	0x0086 00134 (/home/yukatan/freegc/main.go:9)	CALL	runtime.growslice(SB)
	0x008b 00139 (/home/yukatan/freegc/main.go:9)	MOVQ	main.i+72(SP), DX
	0x0090 00144 (/home/yukatan/freegc/main.go:9)	MOVQ	AX, R8
	0x0093 00147 (/home/yukatan/freegc/main.go:9)	MOVQ	CX, AX
	0x0096 00150 (/home/yukatan/freegc/main.go:9)	MOVBLZX	main..autotmp_8+71(SP), R9
	0x009c 00156 (/home/yukatan/freegc/main.go:9)	JMP	34
	0x009e 00158 (/home/yukatan/freegc/main.go:11)	ADDQ	$112, SP
	0x00a2 00162 (/home/yukatan/freegc/main.go:11)	POPQ	BP
	0x00a3 00163 (/home/yukatan/freegc/main.go:11)	RET
	0x00a4 00164 (/home/yukatan/freegc/main.go:11)	NOP
	0x00a4 00164 (/home/yukatan/freegc/main.go:5)	PCDATA	$1, $-1
	0x00a4 00164 (/home/yukatan/freegc/main.go:5)	PCDATA	$0, $-2
	0x00a4 00164 (/home/yukatan/freegc/main.go:5)	CALL	runtime.morestack_noctxt(SB)
	0x00a9 00169 (/home/yukatan/freegc/main.go:5)	PCDATA	$0, $-1
	0x00a9 00169 (/home/yukatan/freegc/main.go:5)	JMP	0
...

Moreover, the corresponding tests are not passed:

$ cd $GOROOT/src/cmd/compile/internal/test
$ GOEXPERIMENT=runtimefreegc go test -run=FreeAppendAllocations -v

=== RUN   TestFreeAppendAllocations
=== RUN   TestFreeAppendAllocations/slice-no-alias
    free_test.go:34: allocs: 5
    free_test.go:36: allocs: 5, want 1
=== RUN   TestFreeAppendAllocations/slice-aliased
    free_test.go:50: allocs: 5
--- FAIL: TestFreeAppendAllocations (0.00s)
    --- FAIL: TestFreeAppendAllocations/slice-no-alias (0.00s)
    --- PASS: TestFreeAppendAllocations/slice-aliased (0.00s)
FAIL
exit status 1
FAIL	cmd/compile/internal/test	0.003s

What did you expect to see?

I suppose that goexperiment.RuntimeFreegc is always false for the compiler, and we should use buildcfg.Experiment.RuntimeFreegc in the corresponding files (ssa.go, escape.go) instead. With this fix, everything works good:

$ GOEXPERIMENT=runtimefreegc go build -gcflags='-S' -o /dev/null ./main.go

main.main STEXT size=174 align=0x0 args=0x0 locals=0x78 funcid=0x0
	0x0000 00000 (/home/yukatan/freegc/main.go:5)	TEXT	main.main(SB), ABIInternal, $120-0
	0x0000 00000 (/home/yukatan/freegc/main.go:5)	CMPQ	SP, 16(R14)
	0x0004 00004 (/home/yukatan/freegc/main.go:5)	PCDATA	$0, $-2
	0x0004 00004 (/home/yukatan/freegc/main.go:5)	JLS	164
....
	0x0072 00114 (/home/yukatan/freegc/main.go:9)	JMP	34
	0x0074 00116 (/home/yukatan/freegc/main.go:9)	MOVQ	AX, CX
	0x0077 00119 (/home/yukatan/freegc/main.go:9)	MOVL	$1, DI
	0x007c 00124 (/home/yukatan/freegc/main.go:9)	LEAQ	type:int(SB), SI
	0x0083 00131 (/home/yukatan/freegc/main.go:9)	MOVQ	R8, AX
	0x0086 00134 (/home/yukatan/freegc/main.go:9)	PCDATA	$1, $0
	0x0086 00134 (/home/yukatan/freegc/main.go:9)	CALL	runtime.growsliceNoAlias(SB)
	0x008b 00139 (/home/yukatan/freegc/main.go:9)	MOVQ	main.i+72(SP), DX
	0x0090 00144 (/home/yukatan/freegc/main.go:9)	MOVQ	AX, R8
	0x0093 00147 (/home/yukatan/freegc/main.go:9)	MOVQ	CX, AX
...
$ cd $GOROOT/src/cmd/compile/internal/test
$ GOEXPERIMENT=runtimefreegc go test -run=FreeAppendAllocations -v
=== RUN   TestFreeAppendAllocations
=== RUN   TestFreeAppendAllocations/slice-no-alias
    free_test.go:34: allocs: 1
=== RUN   TestFreeAppendAllocations/slice-aliased
    free_test.go:50: allocs: 5
--- PASS: TestFreeAppendAllocations (0.00s)
    --- PASS: TestFreeAppendAllocations/slice-no-alias (0.00s)
    --- PASS: TestFreeAppendAllocations/slice-aliased (0.00s)
PASS
ok  	cmd/compile/internal/test	0.003s

Metadata

Metadata

Assignees

No one assigned

    Labels

    compiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions