-
Notifications
You must be signed in to change notification settings - Fork 18.7k
Description
What version of Go are you using (go version)?
go version go1.8 darwin/amd64
building code for PPC64LE.
package main
import (
"fmt"
)
type S struct {
A, B int64
}
type T struct {
ss []S
}
func (t *T) F(s S) {
n := len(t.ss) - 1
for ; n >= 0; n-- {
if t.ss[n].A < s.B {
fmt.Println(s, n, t.ss[n])
panic("A")
}
if t.ss[n-1].B == s.A && s.B == t.ss[n].A {
t.ss = append(t.ss[0:n-1],
append([]S{S{A: t.ss[n-1].A, B: t.ss[n].B}},
t.ss[n+1:len(t.ss)]...)...)
return
}
}
panic("XXX")
}
func main() {
t := &T{ss: []S{{1, 4}, {7, 8}}}
fmt.Println(t)
t.F(S{4, 7})
fmt.Println(t) // should be &{[{1 8}]}
}
Building this program on PPC64LE with Go 1.8, the result's len is wrong, so it prints something like &{[{1 8} {7 8} {842350502368 2} {2 0} {9021871350425025318 9033514107587230496} {10 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0}]}
instead of &{[{1 8}]}, which it prints on AMD64.
On tip, it produces the right result.
Look at ssa.html, before regalloc (looking at flagalloc column), we have v311 = ADD <int> v135 v261 in b35. After regalloc, it becomes
v311 = ADD <int> v33 v401 : R5 (in b35), where
v33 = LoadReg <int> v364 : R3 (in b35),
v364 = StoreReg <int> v135 : .autotmp_31[int] (in b7), which is the spill of v135.
However, in b21, there is also v403 = StoreReg <int> v395 : .autotmp_31[int] which is on the code path, and clobbers the stack slot.
The bad spill (v403) is originally generated in b8, and the spill sinking code moves it to b21, which is problematic. If spill sinking is disabled, it runs fine.
The bug does not exist on tip, as @randall77 rewrote the spill placement code. But we probably need to fix Go 1.8.