1// run
2
3// Copyright 2021 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7// A test for partial liveness / partial spilling / compiler-induced GC failure
8
9package main
10
11import "runtime"
12import "unsafe"
13
14//go:registerparams
15func F(s []int) {
16	for i, x := range s {
17		G(i, x)
18	}
19	GC()
20	H(&s[0]) // It's possible that this will make the spill redundant, but there's a bug in spill slot allocation.
21	G(len(s), cap(s))
22	GC()
23}
24
25//go:noinline
26//go:registerparams
27func G(int, int) {}
28
29//go:noinline
30//go:registerparams
31func H(*int) {}
32
33//go:registerparams
34func GC() { runtime.GC(); runtime.GC() }
35
36func main() {
37	s := make([]int, 3)
38	escape(s)
39	p := int(uintptr(unsafe.Pointer(&s[2])) + 42) // likely point to unallocated memory
40	poison([3]int{p, p, p})
41	F(s)
42}
43
44//go:noinline
45//go:registerparams
46func poison([3]int) {}
47
48//go:noinline
49//go:registerparams
50func escape(s []int) {
51	g = s
52}
53var g []int
54