1// run
2
3//go:build !wasm
4
5// Copyright 2021 The Go Authors. All rights reserved.
6// Use of this source code is governed by a BSD-style
7// license that can be found in the LICENSE file.
8
9// wasm is excluded because the compiler chatter about register abi pragma ends up
10// on stdout, and causes the expected output to not match.
11
12package main
13
14import "fmt"
15
16// This test is designed to provoke a stack growth
17// in a way that very likely leaves junk in the
18// parameter save area if they aren't saved or spilled
19// there, as appropriate.
20
21//go:registerparams
22//go:noinline
23func f(x int, xm1, xm2, p *int) {
24	var y = [2]int{x - 4, 0}
25	if x < 2 {
26		*p += x
27		return
28	}
29	x -= 3
30	g(*xm1, xm2, &x, p)   // xm1 is no longer live.
31	h(*xm2, &x, &y[0], p) // xm2 is no longer live, but was spilled.
32}
33
34//go:registerparams
35//go:noinline
36func g(x int, xm1, xm2, p *int) {
37	var y = [3]int{x - 4, 0, 0}
38	if x < 2 {
39		*p += x
40		return
41	}
42	x -= 3
43	k(*xm2, &x, &y[0], p)
44	h(*xm1, xm2, &x, p)
45}
46
47//go:registerparams
48//go:noinline
49func h(x int, xm1, xm2, p *int) {
50	var y = [4]int{x - 4, 0, 0, 0}
51	if x < 2 {
52		*p += x
53		return
54	}
55	x -= 3
56	k(*xm1, xm2, &x, p)
57	f(*xm2, &x, &y[0], p)
58}
59
60//go:registerparams
61//go:noinline
62func k(x int, xm1, xm2, p *int) {
63	var y = [5]int{x - 4, 0, 0, 0, 0}
64	if x < 2 {
65		*p += x
66		return
67	}
68	x -= 3
69	f(*xm2, &x, &y[0], p)
70	g(*xm1, xm2, &x, p)
71}
72
73func main() {
74	x := 40
75	var y int
76	xm1 := x - 1
77	xm2 := x - 2
78	f(x, &xm1, &xm2, &y)
79
80	fmt.Printf("Fib(%d)=%d\n", x, y)
81}
82