Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: internal compiler error - 'can't find empty register' on ppc64le builders #34468

Closed
ALTree opened this issue Sep 23, 2019 · 7 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. release-blocker
Milestone

Comments

@ALTree
Copy link
Member

ALTree commented Sep 23, 2019

The linux-ppc64le builders are currently broken with a internal compiler error: 'checkIfRange' crash:

##### Testing race detector
# net/http
m:0 unique:58 final:0 rematerializable:0
v2: v2 SP
v414: v414 R3
v205: v205 R4
v459: v348 R5
v458: v458 modtime+8[int64]
v457: v457 modtime+16[*time.Location]
net/http/fs.go:448:14: internal compiler error: 'checkIfRange': can't find empty register on edge b61->b65

goroutine 1 [running]:
runtime/debug.Stack(0xadf820, 0xc000086008, 0x0)
	/tmp/workdir-host-linux-ppc64le-osu/go/src/runtime/debug/stack.go:24 +0x8c
cmd/compile/internal/gc.Fatalf(0xc002c89170, 0x2e, 0xc002d93b00, 0x3, 0x3)
	/tmp/workdir-host-linux-ppc64le-osu/go/src/cmd/compile/internal/gc/subr.go:188 +0x294
cmd/compile/internal/gc.(*ssafn).Fatalf(0xc002f254d0, 0x1c00e000000007, 0x93d17d, 0x28, 0xc002d8d9e0, 0x2, 0x2)
	/tmp/workdir-host-linux-ppc64le-osu/go/src/cmd/compile/internal/gc/ssa.go:6177 +0x160
cmd/compile/internal/ssa.(*Func).Fatalf(...)
	/tmp/workdir-host-linux-ppc64le-osu/go/src/cmd/compile/internal/ssa/func.go:617
cmd/compile/internal/ssa.(*edgeState).findRegFor(0xc002da4a90, 0xc0000883c0, 0xc002da4908, 0xc002ebdca8)
	/tmp/workdir-host-linux-ppc64le-osu/go/src/cmd/compile/internal/ssa/regalloc.go:2287 +0x3dc
cmd/compile/internal/ssa.(*edgeState).process(0xc002da4a90)
	/tmp/workdir-host-linux-ppc64le-osu/go/src/cmd/compile/internal/ssa/regalloc.go:2010 +0x308
cmd/compile/internal/ssa.(*regAllocState).shuffle(0xc002f2b200, 0xc002f03800, 0x49, 0x49)
	/tmp/workdir-host-linux-ppc64le-osu/go/src/cmd/compile/internal/ssa/regalloc.go:1848 +0x204
cmd/compile/internal/ssa.(*regAllocState).regalloc(0xc002f2b200, 0xc002eaac60)
	/tmp/workdir-host-linux-ppc64le-osu/go/src/cmd/compile/internal/ssa/regalloc.go:1659 +0x18d0
cmd/compile/internal/ssa.regalloc(0xc002eaac60)
	/tmp/workdir-host-linux-ppc64le-osu/go/src/cmd/compile/internal/ssa/regalloc.go:146 +0x5c
cmd/compile/internal/ssa.Compile(0xc002eaac60)
	/tmp/workdir-host-linux-ppc64le-osu/go/src/cmd/compile/internal/ssa/compile.go:92 +0x8a4
cmd/compile/internal/gc.buildssa(0xc0008dc160, 0x0, 0x0)
	/tmp/workdir-host-linux-ppc64le-osu/go/src/cmd/compile/internal/gc/ssa.go:289 +0x778
cmd/compile/internal/gc.compileSSA(0xc0008dc160, 0x0)
	/tmp/workdir-host-linux-ppc64le-osu/go/src/cmd/compile/internal/gc/pgen.go:298 +0x38
cmd/compile/internal/gc.compile(0xc0008dc160)
	/tmp/workdir-host-linux-ppc64le-osu/go/src/cmd/compile/internal/gc/pgen.go:277 +0x26c
cmd/compile/internal/gc.funccompile(0xc0008dc160)
	/tmp/workdir-host-linux-ppc64le-osu/go/src/cmd/compile/internal/gc/pgen.go:222 +0xe8
cmd/compile/internal/gc.Main(0x949c48)
	/tmp/workdir-host-linux-ppc64le-osu/go/src/cmd/compile/internal/gc/main.go:682 +0x3184
main.main()
	/tmp/workdir-host-linux-ppc64le-osu/go/src/cmd/compile/main.go:51 +0xb8

2019/09/23 06:03:30 Failed: exit status 2
2019/09/23 06:03:50 FAILED

Full log: https://build.golang.org/log/b288cd59a7c053c8cf0136972f9c37c42bc678c6

The breakage started after CL 194297 (compile: prefer an AND instead of SHR+SHL instructions).

cc @martisch

@ALTree ALTree added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Sep 23, 2019
@ALTree ALTree added this to the Go1.14 milestone Sep 23, 2019
@martisch
Copy link
Contributor

martisch commented Sep 23, 2019

@laboger. I do not currently have a ppc64le machine setup to test and debug this. Could you please have a look if there is an easy fix for ppc64le specific forward?

Note that on linux/amd64 I can not test the race compile since CGO_ENABLED=1 GOARCH=ppc64le go build -race net/http` does not seem to work without a cross compile gcc toolchain setup.

As this error only happens in race and on ppc64le (ppc64 doesnt seem to support -race builds) at first it seems a ppc64 local problem. But since cl/194297 can introduce the use of an extra register to load a large constant where it previously did not this could have increased the register pressure above a threshold when compiling the checkIfRange function in race mode. If that is the case could registers be spilled to resolve the problem?

Seems other changes could run into this problem (potentially also on other platforms) too if not resolved generally.

func checkIfRange(w ResponseWriter, r *Request, modtime time.Time) condResult {

cc @randall77 @cherrymui

@martisch martisch changed the title cmd/compile: internal compiler error: checkIfRange on ppc64le builders cmd/compile: internal compiler error - 'can't find empty register' on ppc64le builders Sep 23, 2019
@gopherbot
Copy link

Change https://golang.org/cl/196957 mentions this issue: Revert "compile: prefer an AND instead of SHR+SHL instructions"

gopherbot pushed a commit that referenced this issue Sep 23, 2019
This reverts CL 194297.

Reason for revert: introduced register allocation failures on PPC64LE builders.

Updates #33826
Updates #32781
Updates #34468

Change-Id: I7d0b55df8cdf8e7d2277f1814299b083c2692e48
Reviewed-on: https://go-review.googlesource.com/c/go/+/196957
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Martin Möhrmann <moehrmann@google.com>
@randall77
Copy link
Contributor

This is strange. The register allocator is reporting m==0 in (*edgeState).findRegFor.
That's shouldn't happen. m is initialized (and then never modified) to

	var m regMask
	if typ.IsFloat() {
		m = e.s.compatRegs(types.Float64)
	} else {
		m = e.s.compatRegs(types.Int64)
	}

Both those calls should return nonzero.

@cherrymui
Copy link
Member

CL 195117 changes it to call compatRegs with typ, and let compatRegs to find the one for the given type. If is float or int, it should be fine. But if typ is flags, the behavior changes: it used to return integer register's mask, now it returns 0. In this particular case, typ is in fact flags. I thought we shouldn't have flags type here?

The interesting value here is v205, which is of type flags but got register R4. This seems bad.

  b61: <- b59
    v352 = MOVDaddr <*int64> {time.t} [8] v2 : R3
    v412 = MOVDstore <mem> [32] v2 v352 v387
    v413 = CALLstatic <mem> {runtime.raceread} [40] v412
    v414 = MOVDload <int64> {time.t} [8] v2 v413 : R3 (~R0[int64])
    v348 = LoadReg <uint64> v459 : R5
    v62 = MOVDconst <uint64> [-9223372036854775808] : R4
    v205 = ANDCC <flags> v348 v62 : R4
    Plain -> b65

@cherrymui
Copy link
Member

PPC64Ops.go has:

		{name: "ANDCC", argLength: 2, reg: gp21, asm: "ANDCC", commutative: true, typ: "Flags"}, // arg0&arg1 sets CC

I think this is not right. It should have a tuple type like (Int64, Flags) instead of flags type.

@randall77
Copy link
Contributor

I think ANDCC doesn't generate the result of the AND, just the flags. So the fix might be as simple as replacing gp21 with gp2flags.

@gopherbot
Copy link

Change https://golang.org/cl/196960 mentions this issue: cmd/compile: fix register masks of ANDCC et al. on PPC64

@golang golang locked and limited conversation to collaborators Sep 22, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. release-blocker
Projects
None yet
Development

No branches or pull requests

5 participants