• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5// This test makes sure that we don't split a single
6// load up into two separate loads.
7
8package main
9
10import "testing"
11
12//go:noinline
13func read1(b []byte) (uint16, uint16) {
14	// There is only a single read of b[0].  The two
15	// returned values must have the same low byte.
16	v := b[0]
17	return uint16(v), uint16(v) | uint16(b[1])<<8
18}
19
20func main1(t *testing.T) {
21	const N = 100000
22	done := make(chan bool, 2)
23	b := make([]byte, 2)
24	go func() {
25		for i := 0; i < N; i++ {
26			b[0] = byte(i)
27			b[1] = byte(i)
28		}
29		done <- true
30	}()
31	go func() {
32		for i := 0; i < N; i++ {
33			x, y := read1(b)
34			if byte(x) != byte(y) {
35				t.Errorf("x=%x y=%x\n", x, y)
36				done <- false
37				return
38			}
39		}
40		done <- true
41	}()
42	<-done
43	<-done
44}
45
46//go:noinline
47func read2(b []byte) (uint16, uint16) {
48	// There is only a single read of b[1].  The two
49	// returned values must have the same high byte.
50	v := uint16(b[1]) << 8
51	return v, uint16(b[0]) | v
52}
53
54func main2(t *testing.T) {
55	const N = 100000
56	done := make(chan bool, 2)
57	b := make([]byte, 2)
58	go func() {
59		for i := 0; i < N; i++ {
60			b[0] = byte(i)
61			b[1] = byte(i)
62		}
63		done <- true
64	}()
65	go func() {
66		for i := 0; i < N; i++ {
67			x, y := read2(b)
68			if x&0xff00 != y&0xff00 {
69				t.Errorf("x=%x y=%x\n", x, y)
70				done <- false
71				return
72			}
73		}
74		done <- true
75	}()
76	<-done
77	<-done
78}
79
80func TestDupLoad(t *testing.T) {
81	main1(t)
82	main2(t)
83}
84