Skip to content

cmd/compile: bug in spill sinking #20472

@cherrymui

Description

@cherrymui

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions