cmd/compile: internal compiler error: panic during lower
ALTree opened this issue · 2 comments
$ gotip version
go version devel +944a9c7a4f Thu Dec 13 06:33:18 2018 +0000 windows/amd64
The following program
package p
func f() {
var s string
var p, q bool
s = "a"
for p {
p = false == (true != q)
s = ""
}
_ = s == "bbb"
}
crashes the tip compiler with:
$ gotip build crash.go
# command-line-arguments
.\crash.go:11:8: internal compiler error: 'f': panic during lower while compiling f:
runtime error: index out of range
goroutine 21 [running]:
cmd/compile/internal/ssa.Compile.func1(0xc0003ef108, 0xc0000be6e0)
go/src/cmd/compile/internal/ssa/compile.go:45 +0xac
panic(0xd7d140, 0x15551c0)
go/src/runtime/panic.go:513 +0x1c5
cmd/compile/internal/ssa.read8(...)
go/src/cmd/compile/internal/ssa/rewrite.go:1140
cmd/compile/internal/ssa.rewriteValueAMD64_OpAMD64MOVBload_0(0xc000395378, 0xc000395a01)
go/src/cmd/compile/internal/ssa/rewriteAMD64.go:12599 +0x95b
cmd/compile/internal/ssa.rewriteValueAMD64(0xc000395378, 0x0)
go/src/cmd/compile/internal/ssa/rewriteAMD64.go:255 +0x2b41
cmd/compile/internal/ssa.applyRewrite(0xc0000be6e0, 0xe10e00, 0xe10e68)
go/src/cmd/compile/internal/ssa/rewrite.go:80 +0x34d
cmd/compile/internal/ssa.lower(0xc0000be6e0)
go/src/cmd/compile/internal/ssa/lower.go:10 +0x4d
cmd/compile/internal/ssa.Compile(0xc0000be6e0)
go/src/cmd/compile/internal/ssa/compile.go:90 +0x473
cmd/compile/internal/gc.buildssa(0xc0000be2c0, 0x1, 0x0)
go/src/cmd/compile/internal/gc/ssa.go:233 +0xbdc
cmd/compile/internal/gc.compileSSA(0xc0000be2c0, 0x1)
go/src/cmd/compile/internal/gc/pgen.go:280 +0x54
cmd/compile/internal/gc.compileFunctions.func2(0xc000341e60, 0xc000052ad0, 0x1)
go/src/cmd/compile/internal/gc/pgen.go:345 +0x50
created by cmd/compile/internal/gc.compileFunctions
go/src/cmd/compile/internal/gc/pgen.go:343 +0x12f
goroutine 21 [running]:
runtime/debug.Stack(0xf81b00, 0xc00007a008, 0x0)
go/src/runtime/debug/stack.go:24 +0xa4
cmd/compile/internal/gc.Fatalf(0xc000064600, 0x32, 0xc000092640, 0x5, 0x5)
go/src/cmd/compile/internal/gc/subr.go:190 +0x292
cmd/compile/internal/gc.(*ssafn).Fatalf(0xc000067fb0, 0xb08000000002, 0xe05637, 0x2c, 0xc0003113c0, 0x4, 0x4)
go/src/cmd/compile/internal/gc/ssa.go:5830 +0x1b7
cmd/compile/internal/ssa.(*Func).Fatalf(...)
go/src/cmd/compile/internal/ssa/func.go:577
cmd/compile/internal/ssa.Compile.func1(0xc0003ef108, 0xc0000be6e0)
go/src/cmd/compile/internal/ssa/compile.go:47 +0x225
panic(0xd7d140, 0x15551c0)
go/src/runtime/panic.go:513 +0x1c5
cmd/compile/internal/ssa.read8(...)
go/src/cmd/compile/internal/ssa/rewrite.go:1140
cmd/compile/internal/ssa.rewriteValueAMD64_OpAMD64MOVBload_0(0xc000395378, 0xc000395a01)
go/src/cmd/compile/internal/ssa/rewriteAMD64.go:12599 +0x95b
cmd/compile/internal/ssa.rewriteValueAMD64(0xc000395378, 0x0)
go/src/cmd/compile/internal/ssa/rewriteAMD64.go:255 +0x2b41
cmd/compile/internal/ssa.applyRewrite(0xc0000be6e0, 0xe10e00, 0xe10e68)
go/src/cmd/compile/internal/ssa/rewrite.go:80 +0x34d
cmd/compile/internal/ssa.lower(0xc0000be6e0)
go/src/cmd/compile/internal/ssa/lower.go:10 +0x4d
cmd/compile/internal/ssa.Compile(0xc0000be6e0)
go/src/cmd/compile/internal/ssa/compile.go:90 +0x473
cmd/compile/internal/gc.buildssa(0xc0000be2c0, 0x1, 0x0)
go/src/cmd/compile/internal/gc/ssa.go:233 +0xbdc
cmd/compile/internal/gc.compileSSA(0xc0000be2c0, 0x1)
go/src/cmd/compile/internal/gc/pgen.go:280 +0x54
cmd/compile/internal/gc.compileFunctions.func2(0xc000341e60, 0xc000052ad0, 0x1)
go/src/cmd/compile/internal/gc/pgen.go:345 +0x50
created by cmd/compile/internal/gc.compileFunctions
go/src/cmd/compile/internal/gc/pgen.go:343 +0x12f
It compiles fine on go1.11.
This is a weird dead code situation. Basically we have
s := "a"
if len(s) == 3 {
load s[0], s[1], and s[2]
}
The compiler realizes that the branch is never taken. And it constant folds "a"
into all occurrences of s
. But the dead code load "a"[1]
is still floating around in the SSA form - it hasn't been removed yet. When the rewrite engine tries to evaluate "a"[1]
at compile time, it barfs.
The easy fix is to just check for and ignore out-of-bounds errors in the rewrite rule. That bounds check was a nice sanity check, but dead code is insane.
A bigger fix is another deadcode pass before lowering. I don't want to go there for this issue.
Change https://golang.org/cl/154057 mentions this issue: cmd/compile: ignore out-of-bounds reads from readonly constants