1
2
3
4
5 package ssa
6
7 import (
8 "cmd/compile/internal/rttype"
9 "reflect"
10 "testing"
11 "unsafe"
12 )
13
14
15
16 func TestMove(t *testing.T) {
17 x := [...]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40}
18 copy(x[1:], x[:])
19 for i := 1; i < len(x); i++ {
20 if int(x[i]) != i {
21 t.Errorf("Memmove got converted to OpMove in alias-unsafe way. Got %d instead of %d in position %d", int(x[i]), i, i+1)
22 }
23 }
24 }
25
26 func TestMoveSmall(t *testing.T) {
27 x := [...]byte{1, 2, 3, 4, 5, 6, 7}
28 copy(x[1:], x[:])
29 for i := 1; i < len(x); i++ {
30 if int(x[i]) != i {
31 t.Errorf("Memmove got converted to OpMove in alias-unsafe way. Got %d instead of %d in position %d", int(x[i]), i, i+1)
32 }
33 }
34 }
35
36 func TestSubFlags(t *testing.T) {
37 if !subFlags32(0, 1).lt() {
38 t.Errorf("subFlags32(0,1).lt() returned false")
39 }
40 if !subFlags32(0, 1).ult() {
41 t.Errorf("subFlags32(0,1).ult() returned false")
42 }
43 }
44
45 func TestIsPPC64WordRotateMask(t *testing.T) {
46 tests := []struct {
47 input int64
48 expected bool
49 }{
50 {0x00000001, true},
51 {0x80000001, true},
52 {0x80010001, false},
53 {0xFFFFFFFA, false},
54 {0xF0F0F0F0, false},
55 {0xFFFFFFFD, true},
56 {0x80000000, true},
57 {0x00000000, false},
58 {0xFFFFFFFF, true},
59 {0x0000FFFF, true},
60 {0xFF0000FF, true},
61 {0x00FFFF00, true},
62 }
63
64 for _, v := range tests {
65 if v.expected != isPPC64WordRotateMask(v.input) {
66 t.Errorf("isPPC64WordRotateMask(0x%x) failed", v.input)
67 }
68 }
69 }
70
71 func TestEncodeDecodePPC64WordRotateMask(t *testing.T) {
72 tests := []struct {
73 rotate int64
74 mask uint64
75 nbits,
76 mb,
77 me,
78 encoded int64
79 }{
80 {1, 0x00000001, 32, 31, 31, 0x20011f20},
81 {2, 0x80000001, 32, 31, 0, 0x20021f01},
82 {3, 0xFFFFFFFD, 32, 31, 29, 0x20031f1e},
83 {4, 0x80000000, 32, 0, 0, 0x20040001},
84 {5, 0xFFFFFFFF, 32, 0, 31, 0x20050020},
85 {6, 0x0000FFFF, 32, 16, 31, 0x20061020},
86 {7, 0xFF0000FF, 32, 24, 7, 0x20071808},
87 {8, 0x00FFFF00, 32, 8, 23, 0x20080818},
88
89 {9, 0x0000000000FFFF00, 64, 40, 55, 0x40092838},
90 {10, 0xFFFF000000000000, 64, 0, 15, 0x400A0010},
91 {10, 0xFFFF000000000001, 64, 63, 15, 0x400A3f10},
92 }
93
94 for i, v := range tests {
95 result := encodePPC64RotateMask(v.rotate, int64(v.mask), v.nbits)
96 if result != v.encoded {
97 t.Errorf("encodePPC64RotateMask(%d,0x%x,%d) = 0x%x, expected 0x%x", v.rotate, v.mask, v.nbits, result, v.encoded)
98 }
99 rotate, mb, me, mask := DecodePPC64RotateMask(result)
100 if rotate != v.rotate || mb != v.mb || me != v.me || mask != v.mask {
101 t.Errorf("DecodePPC64Failure(Test %d) got (%d, %d, %d, %x) expected (%d, %d, %d, %x)", i, rotate, mb, me, mask, v.rotate, v.mb, v.me, v.mask)
102 }
103 }
104 }
105
106 func TestMergePPC64ClrlsldiSrw(t *testing.T) {
107 tests := []struct {
108 clrlsldi int32
109 srw int64
110 valid bool
111 rotate int64
112 mask uint64
113 }{
114
115 {newPPC64ShiftAuxInt(4, 56, 63, 64), 4, true, 0, 0xFF0},
116
117 {newPPC64ShiftAuxInt(4, 48, 63, 64), 4, true, 0, 0xFFFF0},
118
119 {newPPC64ShiftAuxInt(17, 48, 63, 64), 4, false, 0, 0},
120
121 {newPPC64ShiftAuxInt(16, 48, 63, 64), 4, true, 12, 0xFFFF0000},
122
123 {newPPC64ShiftAuxInt(17, 48, 63, 64), 32, false, 0, 0},
124 }
125 for i, v := range tests {
126 result := mergePPC64ClrlsldiSrw(int64(v.clrlsldi), v.srw)
127 if v.valid && result == 0 {
128 t.Errorf("mergePPC64ClrlsldiSrw(Test %d) did not merge", i)
129 } else if !v.valid && result != 0 {
130 t.Errorf("mergePPC64ClrlsldiSrw(Test %d) should return 0", i)
131 } else if r, _, _, m := DecodePPC64RotateMask(result); v.rotate != r || v.mask != m {
132 t.Errorf("mergePPC64ClrlsldiSrw(Test %d) got (%d,0x%x) expected (%d,0x%x)", i, r, m, v.rotate, v.mask)
133 }
134 }
135 }
136
137 func TestMergePPC64ClrlsldiRlwinm(t *testing.T) {
138 tests := []struct {
139 clrlsldi int32
140 rlwinm int64
141 valid bool
142 rotate int64
143 mask uint64
144 }{
145
146 {newPPC64ShiftAuxInt(4, 56, 63, 64), encodePPC64RotateMask(4, 0xFF00, 32), false, 0, 0},
147
148 {newPPC64ShiftAuxInt(4, 56, 63, 64), encodePPC64RotateMask(28, 0x0FFFFFFF, 32), true, 0, 0xFF0},
149
150 {newPPC64ShiftAuxInt(4, 48, 63, 64), encodePPC64RotateMask(28, 0xFFFF, 32), true, 0, 0xFFFF0},
151
152 {newPPC64ShiftAuxInt(17, 48, 63, 64), encodePPC64RotateMask(28, 0xFFFF, 32), false, 0, 0},
153
154 {newPPC64ShiftAuxInt(16, 48, 63, 64), encodePPC64RotateMask(28, 0xFFFF, 32), true, 12, 0xFFFF0000},
155
156 {newPPC64ShiftAuxInt(16, 48, 63, 64), encodePPC64RotateMask(28, 0xF000FFFF, 32), true, 12, 0xFFFF0000},
157 }
158 for i, v := range tests {
159 result := mergePPC64ClrlsldiRlwinm(v.clrlsldi, v.rlwinm)
160 if v.valid && result == 0 {
161 t.Errorf("mergePPC64ClrlsldiRlwinm(Test %d) did not merge", i)
162 } else if !v.valid && result != 0 {
163 t.Errorf("mergePPC64ClrlsldiRlwinm(Test %d) should return 0", i)
164 } else if r, _, _, m := DecodePPC64RotateMask(result); v.rotate != r || v.mask != m {
165 t.Errorf("mergePPC64ClrlsldiRlwinm(Test %d) got (%d,0x%x) expected (%d,0x%x)", i, r, m, v.rotate, v.mask)
166 }
167 }
168 }
169
170 func TestMergePPC64SldiSrw(t *testing.T) {
171 tests := []struct {
172 sld int64
173 srw int64
174 valid bool
175 rotate int64
176 mask uint64
177 }{
178 {4, 4, true, 0, 0xFFFFFFF0},
179 {4, 8, true, 28, 0x0FFFFFF0},
180 {0, 0, true, 0, 0xFFFFFFFF},
181 {8, 4, false, 0, 0},
182 {0, 32, false, 0, 0},
183 {0, 31, true, 1, 0x1},
184 {31, 31, true, 0, 0x80000000},
185 {32, 32, false, 0, 0},
186 }
187 for i, v := range tests {
188 result := mergePPC64SldiSrw(v.sld, v.srw)
189 if v.valid && result == 0 {
190 t.Errorf("mergePPC64SldiSrw(Test %d) did not merge", i)
191 } else if !v.valid && result != 0 {
192 t.Errorf("mergePPC64SldiSrw(Test %d) should return 0", i)
193 } else if r, _, _, m := DecodePPC64RotateMask(result); v.rotate != r || v.mask != m {
194 t.Errorf("mergePPC64SldiSrw(Test %d) got (%d,0x%x) expected (%d,0x%x)", i, r, m, v.rotate, v.mask)
195 }
196 }
197 }
198
199 func TestMergePPC64AndSrwi(t *testing.T) {
200 tests := []struct {
201 and int64
202 srw int64
203 valid bool
204 rotate int64
205 mask uint64
206 }{
207 {0x000000FF, 8, true, 24, 0xFF},
208 {0xF00000FF, 8, true, 24, 0xFF},
209 {0x0F0000FF, 4, false, 0, 0},
210 {0x00000000, 4, false, 0, 0},
211 {0xF0000000, 4, false, 0, 0},
212 {0xF0000000, 32, false, 0, 0},
213 {0xFFFFFFFF, 0, true, 0, 0xFFFFFFFF},
214 }
215 for i, v := range tests {
216 result := mergePPC64AndSrwi(v.and, v.srw)
217 if v.valid && result == 0 {
218 t.Errorf("mergePPC64AndSrwi(Test %d) did not merge", i)
219 } else if !v.valid && result != 0 {
220 t.Errorf("mergePPC64AndSrwi(Test %d) should return 0", i)
221 } else if r, _, _, m := DecodePPC64RotateMask(result); v.rotate != r || v.mask != m {
222 t.Errorf("mergePPC64AndSrwi(Test %d) got (%d,0x%x) expected (%d,0x%x)", i, r, m, v.rotate, v.mask)
223 }
224 }
225 }
226
227 func TestDisjointTypes(t *testing.T) {
228 tests := []struct {
229 v1, v2 any
230 expected bool
231 }{
232 {new(int8), new(int8), false},
233 {new(int8), new(float32), false},
234 {new(int8), new(*int8), true},
235 {new(*int8), new(*float32), false},
236 {new(*int8), new(chan<- int8), false},
237 {new(**int8), new(*int8), false},
238 {new(***int8), new(**int8), false},
239 {new(int8), new(chan<- int8), true},
240 {new(int), unsafe.Pointer(nil), false},
241 {new(byte), new(string), false},
242 {new(int), new(string), false},
243 {new(*int8), new(struct{ a, b int }), true},
244 {new(*int8), new(struct {
245 a *int
246 b int
247 }), false},
248 {new(*int8), new(struct {
249 a int
250 b *int
251 }), false},
252 {new(*byte), new(string), false},
253 {new(int), new(struct {
254 a int
255 b *int
256 }), false},
257 {new(float64), new(complex128), false},
258 {new(*byte), new([]byte), false},
259 {new(int), new([]byte), false},
260 {new(int), new([2]*byte), false},
261 {new([2]int), new(*byte), true},
262 }
263 for _, tst := range tests {
264 t1 := rttype.FromReflect(reflect.TypeOf(tst.v1))
265 t2 := rttype.FromReflect(reflect.TypeOf(tst.v2))
266 result := disjointTypes(t1, t2)
267 if result != tst.expected {
268 t.Errorf("disjointTypes(%s, %s) got %t expected %t", t1.String(), t2.String(), result, tst.expected)
269 }
270 }
271 }
272
273
274 func foo(p1 *int64, p2 *float64) int64 {
275 *p1 = 10
276 *p2 = 0
277 return *p1
278 }
279
280 func TestDisjointTypesRun(t *testing.T) {
281 f := float64(0)
282 i := (*int64)(unsafe.Pointer(&f))
283 r := foo(i, &f)
284 if r != 0 {
285 t.Errorf("disjointTypes gives an incorrect answer that leads to an incorrect optimization.")
286 }
287 }
288
View as plain text