1// run
2
3// Copyright 2019 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// Issue 30977: write barrier call clobbers volatile
8// value when there are multiple uses of the value.
9
10package main
11
12import "runtime"
13
14type T struct {
15	a, b, c, d, e string
16}
17
18//go:noinline
19func g() T {
20	return T{"a", "b", "c", "d", "e"}
21}
22
23//go:noinline
24func f() {
25	// The compiler optimizes this to direct copying
26	// the call result to both globals, with write
27	// barriers. The first write barrier call clobbers
28	// the result of g on stack.
29	X = g()
30	Y = X
31}
32
33var X, Y T
34
35const N = 1000
36
37func main() {
38	// Keep GC running so the write barrier is on.
39	go func() {
40		for {
41			runtime.GC()
42		}
43	}()
44
45	for i := 0; i < N; i++ {
46		runtime.Gosched()
47		f()
48		if X != Y {
49			panic("FAIL")
50		}
51	}
52}
53