github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/compile/test/testdata/ctl_test.go (about) 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 7 package main 8 9 import "testing" 10 11 // nor_ssa calculates NOR(a, b). 12 // It is implemented in a way that generates 13 // phi control values. 14 func 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 28 func 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 45 func emptyRange_ssa(b []byte) bool { 46 for _, x := range b { 47 _ = x 48 } 49 return true 50 } 51 52 func testEmptyRange(t *testing.T) { 53 if !emptyRange_ssa([]byte{}) { 54 t.Errorf("emptyRange_ssa([]byte{})=false, want true") 55 } 56 } 57 58 func 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 75 func 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 96 func 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 104 func 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 112 type 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 120 func 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 133 func 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 140 func TestCtl(t *testing.T) { 141 testPhiControl(t) 142 testEmptyRange(t) 143 144 testSwitch(t) 145 testFallthrough(t) 146 147 testFlagOverwrite(t) 148 }