Closed derekparker closed 3 years ago
cc @cherrymui @dr2chase @randall77
Here's smaller reproducible program:
package p
type S struct{}
func (S) M() {}
type I interface {
M()
}
func f(i I) {
o := i.(interface{})
if _, ok := i.(*S); ok {
o = nil
}
println(o)
}
Somehow, expand_calls
does not handle OpSelectN
correctly.
Here's some more debug output using the small reproducer above:
expandsCalls((*S).M)
v2p[v10 = SelectN <mem> [0] v9] = 0
expandsCalls(f)
allOrdered[0] = b3, v10 = SelectN <mem> [0] v9, uses=1
rewriteSelect(v10 = SelectN <mem> [0] v9, v10 = SelectN <mem> [0] v9, 0)
storeArg v7 = Addr <*uint8> {type.interface {}} v3, *uint8, 0
storeArgOrLoad(v41 = SP <uintptr>; v7 = Addr <*uint8> {type.interface {}} v3; v1; *uint8; 0)
storeArg returns v28 = Store <mem> {*uint8} v30 v7 v1
storeArg v33 = IMake <interface {}> v27 v9, interface {}, 0
storeArgOrLoad(v41 = SP <uintptr>; v33 = IMake <interface {}> v27 v9; v32; interface {}; 0)
storeArgOrLoad(v41 = SP <uintptr>; v27 = Phi <uintptr> v16 v29 (o.type[uintptr]); v32; uintptr; 0)
expandsCalls(main)
storeArg returns v24 = Store <mem> {uintptr} v40 v27 v32
storeArgOrLoad(v41 = SP <uintptr>; v9 = Phi <*uint8> v17 v25 (o.data[*uint8]); v24; *uint8; 8)
storeArg returns v11 = Store <mem> {*uint8} v13 v9 v24
v2p[v5 = Arg <I> {i} (i[I])] = 0
v2p[v5 = Arg <I> {i} (i[I])] = 1
v2p[v8 = ITab <*uint8> v5] = 0
v2p[v5 = Arg <I> {i} (i[I])] = 2
v2p[v17 = IData <interface {}> v5 (o.data[*uint8])] = 0
v2p[v32 = SelectN <mem> [0] v31] = 0
v2p[v35 = SelectN <mem> [0] v34] = 0
v2p[v37 = SelectN <mem> [0] v36] = 0
v2p[v39 = SelectN <mem> [0] v38] = 0
allOrdered[0] = b7, v32 = SelectN <mem> [0] v31, uses=1
rewriteSelect(v32 = SelectN <mem> [0] v31, v32 = SelectN <mem> [0] v31, 0)
allOrdered[1] = b7, v35 = SelectN <mem> [0] v34, uses=1
rewriteSelect(v35 = SelectN <mem> [0] v34, v35 = SelectN <mem> [0] v34, 0)
allOrdered[2] = b7, v37 = SelectN <mem> [0] v36, uses=1
rewriteSelect(v37 = SelectN <mem> [0] v36, v37 = SelectN <mem> [0] v36, 0)
allOrdered[3] = b7, v39 = SelectN <mem> [0] v38, uses=1
expandsCalls(S.M)
storeArg v13 = Addr <*uint8> {type.interface {}} v3, *uint8, 0
storeArgOrLoad(v2 = SP <uintptr>; v13 = Addr <*uint8> {type.interface {}} v3; v5; *uint8; 0)
storeArg returns v15 = Store <mem> {*uint8} v7 v13 v5
rewriteSelect(v39 = SelectN <mem> [0] v38, v39 = SelectN <mem> [0] v38, 0)
storeArg v39 = IMake <interface {}> v28 v33, interface {}, 0
allOrdered[4] = b2, v17 = IData <interface {}> v5 (o.data[*uint8]), uses=2
storeArgOrLoad(v2 = SP <uintptr>; v39 = IMake <interface {}> v28 v33; v38; interface {}; 0)
storeArgOrLoad(v2 = SP <uintptr>; v28 = Phi <uintptr> v22 v35 (o.type[uintptr]); v38; uintptr; 0)
storeArg returns v4 = Store <mem> {uintptr} v23 v28 v38
storeArgOrLoad(v2 = SP <uintptr>; v33 = Phi <*uint8> v8 v31 (o.data[*uint8]); v4; *uint8; 8)
storeArg returns v14 = Store <mem> {*uint8} v6 v33 v4
v2p[v38 = SelectN <mem> [0] v37] = 0
v2p[v41 = SelectN <mem> [0] v40] = 0
v2p[v43 = SelectN <mem> [0] v42] = 0
v2p[v45 = SelectN <mem> [0] v44] = 0
allOrdered[0] = b9, v38 = SelectN <mem> [0] v37, uses=1
rewriteSelect(v38 = SelectN <mem> [0] v37, v38 = SelectN <mem> [0] v37, 0)
allOrdered[1] = b9, v41 = SelectN <mem> [0] v40, uses=1
rewriteSelect(v41 = SelectN <mem> [0] v40, v41 = SelectN <mem> [0] v40, 0)
allOrdered[2] = b9, v43 = SelectN <mem> [0] v42, uses=1
rewriteSelect(v43 = SelectN <mem> [0] v42, v43 = SelectN <mem> [0] v42, 0)
allOrdered[3] = b9, v45 = SelectN <mem> [0] v44, uses=1
rewriteSelect(v45 = SelectN <mem> [0] v44, v45 = SelectN <mem> [0] v44, 0)
expandsCalls(I.M)
storeArg v14 = Load <*uint8> v15 v1, uintptr, 0
storeArgOrLoad(v2 = SP <uintptr>; v14 = Load <*uint8> v15 v1; v1; uintptr; 0)
storeArg returns v16 = Store <mem> {uintptr} v6 v14 v1
v2p[v13 = SelectN <mem> [0] v12] = 0
allOrdered[0] = b1, v13 = SelectN <mem> [0] v12, uses=1
rewriteSelect(v13 = SelectN <mem> [0] v12, v13 = SelectN <mem> [0] v12, 0)
rewriteSelect(v17 = IData <interface {}> v5 (o.data[*uint8]), v17 = IData <interface {}> v5 (o.data[*uint8]), 0)
rewriteSelect(v17 = IData <interface {}> v5 (o.data[*uint8]), v5 = Arg <I> {i} (i[I]), 8)
new v19 = Arg <interface {}> {i} [8]
allOrdered[5] = b1, v8 = ITab <*uint8> v5, uses=3
rewriteSelect(v8 = ITab <*uint8> v5, v8 = ITab <*uint8> v5, 0)
rewriteSelect(v8 = ITab <*uint8> v5, v5 = Arg <I> {i} (i[I]), 0)
allOrdered[6] = b1, v5 = Arg <I> {i} (i[I]), uses=0
Change https://golang.org/cl/270057 mentions this issue: cmd/compile: fix load of interface{}-typed OpIData in expand_calls
Change https://golang.org/cl/276952 mentions this issue: cmd/compile: set correct type for OpIData
(Further comment here that I wanted to leave on the CL, but gerrit is almost completely non-functional on Firefox on mobile.)
Specifically I think you should run compilecmp -fn=changed. Also, this reminds me of https://go-review.googlesource.com/c/go/+/229984. Please see Keith’s comment there.
Thanks for digging to find a root cause here.
What version of Go are you using (
go version
)?This also reproduces on tip.
Does this issue reproduce with the latest release?
No, only on tip.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
git clone github.com/openshift/origin
cd pkg/templateservicebroker/servicebroker
GO111MODULE=auto go build
What did you expect to see?
Successful compilation.
What did you see instead?
Here is some prelim debugging output I've collected about what is causing this panic to trigger:
I did a little bit of digging and the problem seems to be that the compiler is not properly decomposing this store into two smaller stores for some reason. I've bisected the tree from 1.15.4 where this worked and I've found the commit that introduced this bug to be https://github.com/golang/go/commit/15f01d6ae9853fd51ee8842d9af93d04ce25458c.
I'm happy to continue working on this and submit a fix, I've spent some time tracking this down and figured I'd at least create an issue and see if there are any obvious things to look at where things may be going wrong from folks who are more familiar with the actual SSA code than I am at the present moment.