1// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package main
6
7// Test to make sure spills of cast-shortened values
8// don't end up spilling the pre-shortened size instead
9// of the post-shortened size.
10
11import (
12	"runtime"
13	"testing"
14)
15
16var data1 [26]int32
17var data2 [26]int64
18
19func init() {
20	for i := 0; i < 26; i++ {
21		// If we spill all 8 bytes of this datum, the 1 in the high-order 4 bytes
22		// will overwrite some other variable in the stack frame.
23		data2[i] = 0x100000000
24	}
25}
26
27func foo() int32 {
28	var a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z int32
29	if always {
30		a = data1[0]
31		b = data1[1]
32		c = data1[2]
33		d = data1[3]
34		e = data1[4]
35		f = data1[5]
36		g = data1[6]
37		h = data1[7]
38		i = data1[8]
39		j = data1[9]
40		k = data1[10]
41		l = data1[11]
42		m = data1[12]
43		n = data1[13]
44		o = data1[14]
45		p = data1[15]
46		q = data1[16]
47		r = data1[17]
48		s = data1[18]
49		t = data1[19]
50		u = data1[20]
51		v = data1[21]
52		w = data1[22]
53		x = data1[23]
54		y = data1[24]
55		z = data1[25]
56	} else {
57		a = int32(data2[0])
58		b = int32(data2[1])
59		c = int32(data2[2])
60		d = int32(data2[3])
61		e = int32(data2[4])
62		f = int32(data2[5])
63		g = int32(data2[6])
64		h = int32(data2[7])
65		i = int32(data2[8])
66		j = int32(data2[9])
67		k = int32(data2[10])
68		l = int32(data2[11])
69		m = int32(data2[12])
70		n = int32(data2[13])
71		o = int32(data2[14])
72		p = int32(data2[15])
73		q = int32(data2[16])
74		r = int32(data2[17])
75		s = int32(data2[18])
76		t = int32(data2[19])
77		u = int32(data2[20])
78		v = int32(data2[21])
79		w = int32(data2[22])
80		x = int32(data2[23])
81		y = int32(data2[24])
82		z = int32(data2[25])
83	}
84	// Lots of phis of the form phi(int32,int64) of type int32 happen here.
85	// Some will be stack phis. For those stack phis, make sure the spill
86	// of the second argument uses the phi's width (4 bytes), not its width
87	// (8 bytes).  Otherwise, a random stack slot gets clobbered.
88
89	runtime.Gosched()
90	return a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z
91}
92
93func TestPhi(t *testing.T) {
94	want := int32(0)
95	got := foo()
96	if got != want {
97		t.Fatalf("want %d, got %d\n", want, got)
98	}
99}
100