Skip to content

cmd/compile: argument escapes when it should not #18001

@cherrymui

Description

@cherrymui

What version of Go are you using (go version)?

tip (0bae74e)

Compile the following code:

func f() {
        var t int
        g(&t)
}

func h(x int) {
        g(&x)
}

func h2() (x int) {
        g(&x)
        return
}

//go:noinline
func g(*int) {}

I think all of the three functions, f, h, h2, should not allocate on heap. But it actually does for all three. For example, f:

	0x0000 00000 (esc.go:3)	TEXT	"".f(SB), $24-0
	0x0000 00000 (esc.go:3)	MOVQ	(TLS), CX
	0x0009 00009 (esc.go:3)	CMPQ	SP, 16(CX)
	0x000d 00013 (esc.go:3)	JLS	76
	0x000f 00015 (esc.go:3)	SUBQ	$24, SP
	0x0013 00019 (esc.go:3)	MOVQ	BP, 16(SP)
	0x0018 00024 (esc.go:3)	LEAQ	16(SP), BP
	0x001d 00029 (esc.go:3)	FUNCDATA	$0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
	0x001d 00029 (esc.go:3)	FUNCDATA	$1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
	0x001d 00029 (esc.go:4)	LEAQ	type.int(SB), AX
	0x0024 00036 (esc.go:4)	MOVQ	AX, (SP)
	0x0028 00040 (esc.go:4)	PCDATA	$0, $0
	0x0028 00040 (esc.go:4)	CALL	runtime.newobject(SB)
	0x002d 00045 (esc.go:4)	MOVQ	8(SP), AX
	0x0032 00050 (esc.go:4)	MOVQ	$0, (AX)
	0x0039 00057 (esc.go:5)	MOVQ	AX, (SP)
	0x003d 00061 (esc.go:5)	PCDATA	$0, $0
	0x003d 00061 (esc.go:5)	CALL	"".g(SB)
	0x0042 00066 (esc.go:6)	MOVQ	16(SP), BP
	0x0047 00071 (esc.go:6)	ADDQ	$24, SP
	0x004b 00075 (esc.go:6)	RET
	0x004c 00076 (esc.go:6)	NOP
	0x004c 00076 (esc.go:3)	PCDATA	$0, $-1
	0x004c 00076 (esc.go:3)	CALL	runtime.morestack_noctxt(SB)
	0x0051 00081 (esc.go:3)	JMP	0

Escape analysis debug output shows

$ go tool compile -m -m esc.go 
esc.go:18: cannot inline g: marked go:noinline
esc.go:3: cannot inline f: non-leaf function
esc.go:8: cannot inline h: non-leaf function
esc.go:12: cannot inline h2: non-leaf function
esc.go:5: &t escapes to heap
esc.go:5: 	from &t (passed to call[argument escapes]) at esc.go:5
esc.go:4: moved to heap: t
esc.go:9: &x escapes to heap
esc.go:9: 	from &x (passed to call[argument escapes]) at esc.go:9
esc.go:8: moved to heap: x
esc.go:13: &x escapes to heap
esc.go:13: 	from &x (passed to call[argument escapes]) at esc.go:13
esc.go:12: moved to heap: x

@dr2chase

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions