Skip to content

cmd/compile: internal compiler error "bad live variable at entry" with map range, map lookup pointer, and optimized struct method call #80102

Description

@aaronbee

Go version

go1.27rc1

Output of go env in your module/workspace:

CC='/opt/homebrew/bin/gcc-15'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='clang++'
GCCGO='gccgo'
GO111MODULE=''
GOARCH='arm64'
GOARM64='v8.0'
GOAUTH='netrc'
GOBIN='/Users/aaronb/go/bin'
GOCACHE='/Users/aaronb/Library/Caches/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/Users/aaronb/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fmessage-length=0 -ffile-prefix-map=/var/folders/ys/0vjht6zn2m7cv3j0p6qvzpsc0000gq/T/go-build4036815222=/tmp/go-build -gno-record-gcc-switches -fno-common'
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMOD='/Users/aaronb/go/src/arista/go.mod'
GOMODCACHE='/Users/aaronb/go/pkg/mod'
GOOS='darwin'
GOPACKAGESDRIVER=''
GOPATH='/Users/aaronb/go'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/Users/aaronb/sdk/go1.27rc1'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/aaronb/Library/Application Support/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/Users/aaronb/sdk/go1.27rc1/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.27rc1'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

Compiled this program using go1.27rc1

package p

func set(*int) {}

type Edge struct {
	V1 int
	V2 int
}

func (e Edge) CanonicalOrder() Edge {
	if e.V1 > e.V2 {
		return Edge{V1: e.V2, V2: e.V1}
	}
	return e
}

func f(edges map[Edge]*int, nodeToEdges map[int]map[Edge]struct{}, nodeID int, e int) {
	eAssociated := len(nodeToEdges[e]) > 0
	for edgeID := range nodeToEdges[nodeID] {
		hostMap := edges[edgeID]
		if hostMap == nil || !eAssociated {
			continue
		}

		var targetNode int
		if edgeID.V2 == nodeID {
			targetNode = edgeID.V1
		} else {
			targetNode = edgeID.V2
		}
		_ = Edge{V1: e, V2: targetNode}.CanonicalOrder()

		set(hostMap)
	}
}

What did you see happen?

/private/tmp/go127ice/repro.go:20:3: internal compiler error: bad live variable at entry of f: hostMap (type *int)

I also compiled from tip and got this stacktrace:

goroutine 9 [running]:
runtime/debug.Stack()
	/Users/aaronb/gosrc/src/runtime/debug/stack.go:26 +0x64
cmd/compile/internal/base.FatalfAt({0x830da000?, 0x6f43?}, {0x10130db0f, 0x24}, {0x6f43831ef468, 0x2, 0x2})
	/Users/aaronb/gosrc/src/cmd/compile/internal/base/print.go:232 +0x210
cmd/compile/internal/liveness.(*Liveness).epilogue(0x6f43830e1080)
	/Users/aaronb/gosrc/src/cmd/compile/internal/liveness/plive.go:864 +0xd00
cmd/compile/internal/liveness.Compute(0x6f4383050a00, 0x6f4382df21c0, 0x68, 0x6f43831dafc0, 0x0)
	/Users/aaronb/gosrc/src/cmd/compile/internal/liveness/plive.go:1403 +0x724
cmd/compile/internal/ssagen.genssa(0x6f4382df21c0, 0x6f43831dafc0)
	/Users/aaronb/gosrc/src/cmd/compile/internal/ssagen/ssa.go:6988 +0xbc
cmd/compile/internal/ssagen.Compile(0x6f4383050a00, 0x0, 0x6f4382c766e0?)
	/Users/aaronb/gosrc/src/cmd/compile/internal/ssagen/pgen.go:314 +0x480
cmd/compile/internal/gc.compileFunctions.func2()
	/Users/aaronb/gosrc/src/cmd/compile/internal/gc/compile.go:177 +0x6c
created by cmd/compile/internal/gc.compileFunctions in goroutine 1
	/Users/aaronb/gosrc/src/cmd/compile/internal/gc/compile.go:163 +0x108

I used OpenAI Codex CLI to make the reproducer from some internal code. Here are some additional notes from Codex about what is required to reproduce:

  1. A pointer value loaded from a map using the map-range key:

hostMap := edges[edgeID]

Changing hostMap to come from a pointer parameter made the repro compile.

  1. A second boolean computed from a map lookup and used in the same continue condition as the nil check:
eAssociated := len(nodeToEdges[e]) > 0

if hostMap == nil || !eAssociated {
      continue
}

Removing eAssociated, or replacing it with a simple scalar expression like e != 0, made the repro compile.

  1. The loop needs to range over a map, not a slice:
for edgeID := range nodeToEdges[nodeID] {

Changing the ranged collection to a slice made the repro compile.

  1. hostMap needs to remain live across a non-trivial value operation involving the ranged key:
var targetNode int
if edgeID.V2 == nodeID {
      targetNode = edgeID.V1
} else {
      targetNode = edgeID.V2
}
_ = Edge{V1: e, V2: targetNode}.CanonicalOrder()

A plain branch or a trivial function call did not reproduce. The CanonicalOrder method also needs real branching; changing it to return e made the repro compile.

  1. The pointer must be used after that operation:

set(hostMap)

Other notes:

  • Inlining: -l still fails.
  • Full optimization: -N makes it compile, so this is likely an optimized SSA/liveness issue.

What did you expect to see?

Successful compilation. It works with go1.26

Metadata

Metadata

Assignees

Labels

FixPendingIssues that have a fix which has not yet been reviewed or submitted.NeedsFixThe path to resolution is known, but the work has not been done.compiler/runtimeIssues related to the Go compiler and/or runtime.

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
In Progress

Relationships

None yet

Development

No branches or pull requests

Issue actions