• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015 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// Test control flow
6
7package main
8
9import "testing"
10
11// nor_ssa calculates NOR(a, b).
12// It is implemented in a way that generates
13// phi control values.
14func nor_ssa(a, b bool) bool {
15	var c bool
16	if a {
17		c = true
18	}
19	if b {
20		c = true
21	}
22	if c {
23		return false
24	}
25	return true
26}
27
28func testPhiControl(t *testing.T) {
29	tests := [...][3]bool{ // a, b, want
30		{false, false, true},
31		{true, false, false},
32		{false, true, false},
33		{true, true, false},
34	}
35	for _, test := range tests {
36		a, b := test[0], test[1]
37		got := nor_ssa(a, b)
38		want := test[2]
39		if want != got {
40			t.Errorf("nor(%t, %t)=%t got %t", a, b, want, got)
41		}
42	}
43}
44
45func emptyRange_ssa(b []byte) bool {
46	for _, x := range b {
47		_ = x
48	}
49	return true
50}
51
52func testEmptyRange(t *testing.T) {
53	if !emptyRange_ssa([]byte{}) {
54		t.Errorf("emptyRange_ssa([]byte{})=false, want true")
55	}
56}
57
58func switch_ssa(a int) int {
59	ret := 0
60	switch a {
61	case 5:
62		ret += 5
63	case 4:
64		ret += 4
65	case 3:
66		ret += 3
67	case 2:
68		ret += 2
69	case 1:
70		ret += 1
71	}
72	return ret
73}
74
75func fallthrough_ssa(a int) int {
76	ret := 0
77	switch a {
78	case 5:
79		ret++
80		fallthrough
81	case 4:
82		ret++
83		fallthrough
84	case 3:
85		ret++
86		fallthrough
87	case 2:
88		ret++
89		fallthrough
90	case 1:
91		ret++
92	}
93	return ret
94}
95
96func testFallthrough(t *testing.T) {
97	for i := 0; i < 6; i++ {
98		if got := fallthrough_ssa(i); got != i {
99			t.Errorf("fallthrough_ssa(i) = %d, wanted %d", got, i)
100		}
101	}
102}
103
104func testSwitch(t *testing.T) {
105	for i := 0; i < 6; i++ {
106		if got := switch_ssa(i); got != i {
107			t.Errorf("switch_ssa(i) = %d, wanted %d", got, i)
108		}
109	}
110}
111
112type junk struct {
113	step int
114}
115
116// flagOverwrite_ssa is intended to reproduce an issue seen where a XOR
117// was scheduled between a compare and branch, clearing flags.
118//
119//go:noinline
120func flagOverwrite_ssa(s *junk, c int) int {
121	if '0' <= c && c <= '9' {
122		s.step = 0
123		return 1
124	}
125	if c == 'e' || c == 'E' {
126		s.step = 0
127		return 2
128	}
129	s.step = 0
130	return 3
131}
132
133func testFlagOverwrite(t *testing.T) {
134	j := junk{}
135	if got := flagOverwrite_ssa(&j, ' '); got != 3 {
136		t.Errorf("flagOverwrite_ssa = %d, wanted 3", got)
137	}
138}
139
140func TestCtl(t *testing.T) {
141	testPhiControl(t)
142	testEmptyRange(t)
143
144	testSwitch(t)
145	testFallthrough(t)
146
147	testFlagOverwrite(t)
148}
149