Skip to content

cmd/compile: incorrect liveness information #19078

@rsc

Description

@rsc

This bug is not present in release-branch.go1.8 nor earlier versions of Go. It is the root cause for some failures reported on #19029 (but not the ones using Go 1.7.5).

Here's a source file:

package p

func g()
func h(*error)

func f(err error) error {
	defer g()
	h(&err)
	return err
}

The liveness debugging output begins:

$ go tool compile -live=2 /tmp/xxx.go
/tmp/xxx.go:6: live at entry to f: err
/tmp/xxx.go:6: live at call to newobject: err ~r1
/tmp/xxx.go:6: live at call to writebarrierptr: ~r1 &err
/tmp/xxx.go:7: live at call to deferproc: ~r1 &err
/tmp/xxx.go:8: live at call to h: ~r1 &err
/tmp/xxx.go:9: live at call to deferreturn: ~r1
/tmp/xxx.go:7: live at call to deferreturn: ~r1
liveness: f
bb#0 pred= succ=2,1
00000 (/tmp/xxx.go:6)	TEXT	"".f(SB)
	varkill=err
	live=err
00001 (/tmp/xxx.go:6)	FUNCDATA	$0, "".gcargs·0(SB)
00002 (/tmp/xxx.go:6)	FUNCDATA	$1, "".gclocals·1(SB)
00003 (/tmp/xxx.go:6)	LEAQ	type.error(SB), AX
00004 (/tmp/xxx.go:6)	MOVQ	AX, (SP)
00047 (/tmp/xxx.go:6)	PCDATA	$0, $1
00005 (/tmp/xxx.go:6)	CALL	runtime.newobject(SB)
	live=err,~r1
00006 (/tmp/xxx.go:6)	MOVQ	8(SP), AX
00007 (/tmp/xxx.go:6)	MOVQ	AX, "".&err-8(SP)
	varkill=&err
00008 (/tmp/xxx.go:6)	MOVQ	"".err(FP), CX
	uevar=err
00009 (/tmp/xxx.go:6)	MOVQ	CX, (AX)
00010 (/tmp/xxx.go:6)	MOVL	runtime.writeBarrier(SB), CX
00011 (/tmp/xxx.go:6)	LEAQ	8(AX), DX
00012 (/tmp/xxx.go:6)	TESTL	CX, CX
00013 (/tmp/xxx.go:6)	JNE	$0, 40
end
	varkill=err,&err liveout=err,&err

bb#1 pred=0 succ=3
	uevar=err livein=err,&err
00014 (/tmp/xxx.go:6)	MOVQ	"".err+8(FP), CX
	uevar=err
00015 (/tmp/xxx.go:6)	MOVQ	CX, 8(AX)
end
	liveout=&err

bb#2 pred=0 succ=3
	uevar=err,&err livein=err,&err
00040 (/tmp/xxx.go:6)	MOVQ	DX, (SP)
00041 (/tmp/xxx.go:6)	MOVQ	"".err+8(FP), CX
	uevar=err
00042 (/tmp/xxx.go:6)	MOVQ	CX, 8(SP)
00048 (/tmp/xxx.go:6)	PCDATA	$0, $2
00043 (/tmp/xxx.go:6)	CALL	runtime.writebarrierptr(SB)
	live=~r1,&err
00044 (/tmp/xxx.go:8)	MOVQ	"".&err-8(SP), AX
	uevar=&err
00045 (/tmp/xxx.go:6)	JMP	16
end
	liveout=&err

bb#3 pred=2,1 succ=5,4
	livein=&err
00016 (/tmp/xxx.go:6)	VARDEF	"".~r1+16(FP)
	varkill=~r1
00017 (/tmp/xxx.go:6)	MOVQ	$0, "".~r1+16(FP)
00018 (/tmp/xxx.go:6)	MOVQ	$0, "".~r1+24(FP)
00019 (/tmp/xxx.go:7)	MOVL	$0, (SP)
...

Note that in bb 0~r1 has magically become live between the start of the function and the call to newobject. That's wrong. It is not initialized until bb 3.

My guess is this was introduced by Keith's change to the handling of results in liveness bitmaps, but that's just a guess.

Again, not present in Go 1.8rc3, nor in Go 1.7.5. Those correctly delay ~r1 being live until after it is initialized.

/cc @mdempsky @randall77

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions