]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/test/testdata/arith_test.go
all: fix typos in go file comments
[gostls13.git] / src / cmd / compile / internal / test / testdata / arith_test.go
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 // Tests arithmetic expressions
6
7 package main
8
9 import (
10         "math"
11         "runtime"
12         "testing"
13 )
14
15 const (
16         y = 0x0fffFFFF
17 )
18
19 var (
20         g8  int8
21         g16 int16
22         g32 int32
23         g64 int64
24 )
25
26 //go:noinline
27 func lshNop1(x uint64) uint64 {
28         // two outer shifts should be removed
29         return (((x << 5) >> 2) << 2)
30 }
31
32 //go:noinline
33 func lshNop2(x uint64) uint64 {
34         return (((x << 5) >> 2) << 3)
35 }
36
37 //go:noinline
38 func lshNop3(x uint64) uint64 {
39         return (((x << 5) >> 2) << 6)
40 }
41
42 //go:noinline
43 func lshNotNop(x uint64) uint64 {
44         // outer shift can't be removed
45         return (((x << 5) >> 2) << 1)
46 }
47
48 //go:noinline
49 func rshNop1(x uint64) uint64 {
50         return (((x >> 5) << 2) >> 2)
51 }
52
53 //go:noinline
54 func rshNop2(x uint64) uint64 {
55         return (((x >> 5) << 2) >> 3)
56 }
57
58 //go:noinline
59 func rshNop3(x uint64) uint64 {
60         return (((x >> 5) << 2) >> 6)
61 }
62
63 //go:noinline
64 func rshNotNop(x uint64) uint64 {
65         return (((x >> 5) << 2) >> 1)
66 }
67
68 func testShiftRemoval(t *testing.T) {
69         allSet := ^uint64(0)
70         if want, got := uint64(0x7ffffffffffffff), rshNop1(allSet); want != got {
71                 t.Errorf("testShiftRemoval rshNop1 failed, wanted %d got %d", want, got)
72         }
73         if want, got := uint64(0x3ffffffffffffff), rshNop2(allSet); want != got {
74                 t.Errorf("testShiftRemoval rshNop2 failed, wanted %d got %d", want, got)
75         }
76         if want, got := uint64(0x7fffffffffffff), rshNop3(allSet); want != got {
77                 t.Errorf("testShiftRemoval rshNop3 failed, wanted %d got %d", want, got)
78         }
79         if want, got := uint64(0xffffffffffffffe), rshNotNop(allSet); want != got {
80                 t.Errorf("testShiftRemoval rshNotNop failed, wanted %d got %d", want, got)
81         }
82         if want, got := uint64(0xffffffffffffffe0), lshNop1(allSet); want != got {
83                 t.Errorf("testShiftRemoval lshNop1 failed, wanted %d got %d", want, got)
84         }
85         if want, got := uint64(0xffffffffffffffc0), lshNop2(allSet); want != got {
86                 t.Errorf("testShiftRemoval lshNop2 failed, wanted %d got %d", want, got)
87         }
88         if want, got := uint64(0xfffffffffffffe00), lshNop3(allSet); want != got {
89                 t.Errorf("testShiftRemoval lshNop3 failed, wanted %d got %d", want, got)
90         }
91         if want, got := uint64(0x7ffffffffffffff0), lshNotNop(allSet); want != got {
92                 t.Errorf("testShiftRemoval lshNotNop failed, wanted %d got %d", want, got)
93         }
94 }
95
96 //go:noinline
97 func parseLE64(b []byte) uint64 {
98         // skip the first two bytes, and parse the remaining 8 as a uint64
99         return uint64(b[2]) | uint64(b[3])<<8 | uint64(b[4])<<16 | uint64(b[5])<<24 |
100                 uint64(b[6])<<32 | uint64(b[7])<<40 | uint64(b[8])<<48 | uint64(b[9])<<56
101 }
102
103 //go:noinline
104 func parseLE32(b []byte) uint32 {
105         return uint32(b[2]) | uint32(b[3])<<8 | uint32(b[4])<<16 | uint32(b[5])<<24
106 }
107
108 //go:noinline
109 func parseLE16(b []byte) uint16 {
110         return uint16(b[2]) | uint16(b[3])<<8
111 }
112
113 // testLoadCombine tests for issue #14694 where load combining didn't respect the pointer offset.
114 func testLoadCombine(t *testing.T) {
115         testData := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}
116         if want, got := uint64(0x0908070605040302), parseLE64(testData); want != got {
117                 t.Errorf("testLoadCombine failed, wanted %d got %d", want, got)
118         }
119         if want, got := uint32(0x05040302), parseLE32(testData); want != got {
120                 t.Errorf("testLoadCombine failed, wanted %d got %d", want, got)
121         }
122         if want, got := uint16(0x0302), parseLE16(testData); want != got {
123                 t.Errorf("testLoadCombine failed, wanted %d got %d", want, got)
124         }
125 }
126
127 var loadSymData = [...]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}
128
129 func testLoadSymCombine(t *testing.T) {
130         w2 := uint16(0x0201)
131         g2 := uint16(loadSymData[0]) | uint16(loadSymData[1])<<8
132         if g2 != w2 {
133                 t.Errorf("testLoadSymCombine failed, wanted %d got %d", w2, g2)
134         }
135         w4 := uint32(0x04030201)
136         g4 := uint32(loadSymData[0]) | uint32(loadSymData[1])<<8 |
137                 uint32(loadSymData[2])<<16 | uint32(loadSymData[3])<<24
138         if g4 != w4 {
139                 t.Errorf("testLoadSymCombine failed, wanted %d got %d", w4, g4)
140         }
141         w8 := uint64(0x0807060504030201)
142         g8 := uint64(loadSymData[0]) | uint64(loadSymData[1])<<8 |
143                 uint64(loadSymData[2])<<16 | uint64(loadSymData[3])<<24 |
144                 uint64(loadSymData[4])<<32 | uint64(loadSymData[5])<<40 |
145                 uint64(loadSymData[6])<<48 | uint64(loadSymData[7])<<56
146         if g8 != w8 {
147                 t.Errorf("testLoadSymCombine failed, wanted %d got %d", w8, g8)
148         }
149 }
150
151 //go:noinline
152 func invalidAdd_ssa(x uint32) uint32 {
153         return x + y + y + y + y + y + y + y + y + y + y + y + y + y + y + y + y + y
154 }
155
156 //go:noinline
157 func invalidSub_ssa(x uint32) uint32 {
158         return x - y - y - y - y - y - y - y - y - y - y - y - y - y - y - y - y - y
159 }
160
161 //go:noinline
162 func invalidMul_ssa(x uint32) uint32 {
163         return x * y * y * y * y * y * y * y * y * y * y * y * y * y * y * y * y * y
164 }
165
166 // testLargeConst tests a situation where larger than 32 bit consts were passed to ADDL
167 // causing an invalid instruction error.
168 func testLargeConst(t *testing.T) {
169         if want, got := uint32(268435440), invalidAdd_ssa(1); want != got {
170                 t.Errorf("testLargeConst add failed, wanted %d got %d", want, got)
171         }
172         if want, got := uint32(4026531858), invalidSub_ssa(1); want != got {
173                 t.Errorf("testLargeConst sub failed, wanted %d got %d", want, got)
174         }
175         if want, got := uint32(268435455), invalidMul_ssa(1); want != got {
176                 t.Errorf("testLargeConst mul failed, wanted %d got %d", want, got)
177         }
178 }
179
180 // testArithRshConst ensures that "const >> const" right shifts correctly perform
181 // sign extension on the lhs constant
182 func testArithRshConst(t *testing.T) {
183         wantu := uint64(0x4000000000000000)
184         if got := arithRshuConst_ssa(); got != wantu {
185                 t.Errorf("arithRshuConst failed, wanted %d got %d", wantu, got)
186         }
187
188         wants := int64(-0x4000000000000000)
189         if got := arithRshConst_ssa(); got != wants {
190                 t.Errorf("arithRshConst failed, wanted %d got %d", wants, got)
191         }
192 }
193
194 //go:noinline
195 func arithRshuConst_ssa() uint64 {
196         y := uint64(0x8000000000000001)
197         z := uint64(1)
198         return uint64(y >> z)
199 }
200
201 //go:noinline
202 func arithRshConst_ssa() int64 {
203         y := int64(-0x8000000000000000)
204         z := uint64(1)
205         return int64(y >> z)
206 }
207
208 //go:noinline
209 func arithConstShift_ssa(x int64) int64 {
210         return x >> 100
211 }
212
213 // testArithConstShift tests that right shift by large constants preserve
214 // the sign of the input.
215 func testArithConstShift(t *testing.T) {
216         want := int64(-1)
217         if got := arithConstShift_ssa(-1); want != got {
218                 t.Errorf("arithConstShift_ssa(-1) failed, wanted %d got %d", want, got)
219         }
220         want = 0
221         if got := arithConstShift_ssa(1); want != got {
222                 t.Errorf("arithConstShift_ssa(1) failed, wanted %d got %d", want, got)
223         }
224 }
225
226 // overflowConstShift_ssa verifies that constant folding for shift
227 // doesn't wrap (i.e. x << MAX_INT << 1 doesn't get folded to x << 0).
228 //
229 //go:noinline
230 func overflowConstShift64_ssa(x int64) int64 {
231         return x << uint64(0xffffffffffffffff) << uint64(1)
232 }
233
234 //go:noinline
235 func overflowConstShift32_ssa(x int64) int32 {
236         return int32(x) << uint32(0xffffffff) << uint32(1)
237 }
238
239 //go:noinline
240 func overflowConstShift16_ssa(x int64) int16 {
241         return int16(x) << uint16(0xffff) << uint16(1)
242 }
243
244 //go:noinline
245 func overflowConstShift8_ssa(x int64) int8 {
246         return int8(x) << uint8(0xff) << uint8(1)
247 }
248
249 func testOverflowConstShift(t *testing.T) {
250         want := int64(0)
251         for x := int64(-127); x < int64(127); x++ {
252                 got := overflowConstShift64_ssa(x)
253                 if want != got {
254                         t.Errorf("overflowShift64 failed, wanted %d got %d", want, got)
255                 }
256                 got = int64(overflowConstShift32_ssa(x))
257                 if want != got {
258                         t.Errorf("overflowShift32 failed, wanted %d got %d", want, got)
259                 }
260                 got = int64(overflowConstShift16_ssa(x))
261                 if want != got {
262                         t.Errorf("overflowShift16 failed, wanted %d got %d", want, got)
263                 }
264                 got = int64(overflowConstShift8_ssa(x))
265                 if want != got {
266                         t.Errorf("overflowShift8 failed, wanted %d got %d", want, got)
267                 }
268         }
269 }
270
271 // test64BitConstMult tests that rewrite rules don't fold 64 bit constants
272 // into multiply instructions.
273 func test64BitConstMult(t *testing.T) {
274         want := int64(103079215109)
275         if got := test64BitConstMult_ssa(1, 2); want != got {
276                 t.Errorf("test64BitConstMult failed, wanted %d got %d", want, got)
277         }
278 }
279
280 //go:noinline
281 func test64BitConstMult_ssa(a, b int64) int64 {
282         return 34359738369*a + b*34359738370
283 }
284
285 // test64BitConstAdd tests that rewrite rules don't fold 64 bit constants
286 // into add instructions.
287 func test64BitConstAdd(t *testing.T) {
288         want := int64(3567671782835376650)
289         if got := test64BitConstAdd_ssa(1, 2); want != got {
290                 t.Errorf("test64BitConstAdd failed, wanted %d got %d", want, got)
291         }
292 }
293
294 //go:noinline
295 func test64BitConstAdd_ssa(a, b int64) int64 {
296         return a + 575815584948629622 + b + 2991856197886747025
297 }
298
299 // testRegallocCVSpill tests that regalloc spills a value whose last use is the
300 // current value.
301 func testRegallocCVSpill(t *testing.T) {
302         want := int8(-9)
303         if got := testRegallocCVSpill_ssa(1, 2, 3, 4); want != got {
304                 t.Errorf("testRegallocCVSpill failed, wanted %d got %d", want, got)
305         }
306 }
307
308 //go:noinline
309 func testRegallocCVSpill_ssa(a, b, c, d int8) int8 {
310         return a + -32 + b + 63*c*-87*d
311 }
312
313 func testBitwiseLogic(t *testing.T) {
314         a, b := uint32(57623283), uint32(1314713839)
315         if want, got := uint32(38551779), testBitwiseAnd_ssa(a, b); want != got {
316                 t.Errorf("testBitwiseAnd failed, wanted %d got %d", want, got)
317         }
318         if want, got := uint32(1333785343), testBitwiseOr_ssa(a, b); want != got {
319                 t.Errorf("testBitwiseOr failed, wanted %d got %d", want, got)
320         }
321         if want, got := uint32(1295233564), testBitwiseXor_ssa(a, b); want != got {
322                 t.Errorf("testBitwiseXor failed, wanted %d got %d", want, got)
323         }
324         if want, got := int32(832), testBitwiseLsh_ssa(13, 4, 2); want != got {
325                 t.Errorf("testBitwiseLsh failed, wanted %d got %d", want, got)
326         }
327         if want, got := int32(0), testBitwiseLsh_ssa(13, 25, 15); want != got {
328                 t.Errorf("testBitwiseLsh failed, wanted %d got %d", want, got)
329         }
330         if want, got := int32(0), testBitwiseLsh_ssa(-13, 25, 15); want != got {
331                 t.Errorf("testBitwiseLsh failed, wanted %d got %d", want, got)
332         }
333         if want, got := int32(-13), testBitwiseRsh_ssa(-832, 4, 2); want != got {
334                 t.Errorf("testBitwiseRsh failed, wanted %d got %d", want, got)
335         }
336         if want, got := int32(0), testBitwiseRsh_ssa(13, 25, 15); want != got {
337                 t.Errorf("testBitwiseRsh failed, wanted %d got %d", want, got)
338         }
339         if want, got := int32(-1), testBitwiseRsh_ssa(-13, 25, 15); want != got {
340                 t.Errorf("testBitwiseRsh failed, wanted %d got %d", want, got)
341         }
342         if want, got := uint32(0x3ffffff), testBitwiseRshU_ssa(0xffffffff, 4, 2); want != got {
343                 t.Errorf("testBitwiseRshU failed, wanted %d got %d", want, got)
344         }
345         if want, got := uint32(0), testBitwiseRshU_ssa(13, 25, 15); want != got {
346                 t.Errorf("testBitwiseRshU failed, wanted %d got %d", want, got)
347         }
348         if want, got := uint32(0), testBitwiseRshU_ssa(0x8aaaaaaa, 25, 15); want != got {
349                 t.Errorf("testBitwiseRshU failed, wanted %d got %d", want, got)
350         }
351 }
352
353 //go:noinline
354 func testBitwiseAnd_ssa(a, b uint32) uint32 {
355         return a & b
356 }
357
358 //go:noinline
359 func testBitwiseOr_ssa(a, b uint32) uint32 {
360         return a | b
361 }
362
363 //go:noinline
364 func testBitwiseXor_ssa(a, b uint32) uint32 {
365         return a ^ b
366 }
367
368 //go:noinline
369 func testBitwiseLsh_ssa(a int32, b, c uint32) int32 {
370         return a << b << c
371 }
372
373 //go:noinline
374 func testBitwiseRsh_ssa(a int32, b, c uint32) int32 {
375         return a >> b >> c
376 }
377
378 //go:noinline
379 func testBitwiseRshU_ssa(a uint32, b, c uint32) uint32 {
380         return a >> b >> c
381 }
382
383 //go:noinline
384 func testShiftCX_ssa() int {
385         v1 := uint8(3)
386         v4 := (v1 * v1) ^ v1 | v1 - v1 - v1&v1 ^ uint8(3+2) + v1*1>>0 - v1 | 1 | v1<<(2*3|0-0*0^1)
387         v5 := v4>>(3-0-uint(3)) | v1 | v1 + v1 ^ v4<<(0+1|3&1)<<(uint64(1)<<0*2*0<<0) ^ v1
388         v6 := v5 ^ (v1+v1)*v1 | v1 | v1*v1>>(v1&v1)>>(uint(1)<<0*uint(3)>>1)*v1<<2*v1<<v1 - v1>>2 | (v4 - v1) ^ v1 + v1 ^ v1>>1 | v1 + v1 - v1 ^ v1
389         v7 := v6 & v5 << 0
390         v1++
391         v11 := 2&1 ^ 0 + 3 | int(0^0)<<1>>(1*0*3) ^ 0*0 ^ 3&0*3&3 ^ 3*3 ^ 1 ^ int(2)<<(2*3) + 2 | 2 | 2 ^ 2 + 1 | 3 | 0 ^ int(1)>>1 ^ 2 // int
392         v7--
393         return int(uint64(2*1)<<(3-2)<<uint(3>>v7)-2)&v11 | v11 - int(2)<<0>>(2-1)*(v11*0&v11<<1<<(uint8(2)+v4))
394 }
395
396 func testShiftCX(t *testing.T) {
397         want := 141
398         if got := testShiftCX_ssa(); want != got {
399                 t.Errorf("testShiftCX failed, wanted %d got %d", want, got)
400         }
401 }
402
403 // testSubqToNegq ensures that the SUBQ -> NEGQ translation works correctly.
404 func testSubqToNegq(t *testing.T) {
405         want := int64(-318294940372190156)
406         if got := testSubqToNegq_ssa(1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2); want != got {
407                 t.Errorf("testSubqToNegq failed, wanted %d got %d", want, got)
408         }
409 }
410
411 //go:noinline
412 func testSubqToNegq_ssa(a, b, c, d, e, f, g, h, i, j, k int64) int64 {
413         return a + 8207351403619448057 - b - 1779494519303207690 + c*8810076340510052032*d - 4465874067674546219 - e*4361839741470334295 - f + 8688847565426072650*g*8065564729145417479
414 }
415
416 func testOcom(t *testing.T) {
417         want1, want2 := int32(0x55555555), int32(-0x55555556)
418         if got1, got2 := testOcom_ssa(0x55555555, 0x55555555); want1 != got1 || want2 != got2 {
419                 t.Errorf("testOcom failed, wanted %d and %d got %d and %d", want1, want2, got1, got2)
420         }
421 }
422
423 //go:noinline
424 func testOcom_ssa(a, b int32) (int32, int32) {
425         return ^^^^a, ^^^^^b
426 }
427
428 func lrot1_ssa(w uint8, x uint16, y uint32, z uint64) (a uint8, b uint16, c uint32, d uint64) {
429         a = (w << 5) | (w >> 3)
430         b = (x << 13) | (x >> 3)
431         c = (y << 29) | (y >> 3)
432         d = (z << 61) | (z >> 3)
433         return
434 }
435
436 //go:noinline
437 func lrot2_ssa(w, n uint32) uint32 {
438         // Want to be sure that a "rotate by 32" which
439         // is really 0 | (w >> 0) == w
440         // is correctly compiled.
441         return (w << n) | (w >> (32 - n))
442 }
443
444 //go:noinline
445 func lrot3_ssa(w uint32) uint32 {
446         // Want to be sure that a "rotate by 32" which
447         // is really 0 | (w >> 0) == w
448         // is correctly compiled.
449         return (w << 32) | (w >> (32 - 32))
450 }
451
452 func testLrot(t *testing.T) {
453         wantA, wantB, wantC, wantD := uint8(0xe1), uint16(0xe001),
454                 uint32(0xe0000001), uint64(0xe000000000000001)
455         a, b, c, d := lrot1_ssa(0xf, 0xf, 0xf, 0xf)
456         if a != wantA || b != wantB || c != wantC || d != wantD {
457                 t.Errorf("lrot1_ssa(0xf, 0xf, 0xf, 0xf)=%d %d %d %d, got %d %d %d %d", wantA, wantB, wantC, wantD, a, b, c, d)
458         }
459         x := lrot2_ssa(0xb0000001, 32)
460         wantX := uint32(0xb0000001)
461         if x != wantX {
462                 t.Errorf("lrot2_ssa(0xb0000001, 32)=%d, got %d", wantX, x)
463         }
464         x = lrot3_ssa(0xb0000001)
465         if x != wantX {
466                 t.Errorf("lrot3_ssa(0xb0000001)=%d, got %d", wantX, x)
467         }
468
469 }
470
471 //go:noinline
472 func sub1_ssa() uint64 {
473         v1 := uint64(3) // uint64
474         return v1*v1 - (v1&v1)&v1
475 }
476
477 //go:noinline
478 func sub2_ssa() uint8 {
479         v1 := uint8(0)
480         v3 := v1 + v1 + v1 ^ v1 | 3 + v1 ^ v1 | v1 ^ v1
481         v1-- // dev.ssa doesn't see this one
482         return v1 ^ v1*v1 - v3
483 }
484
485 func testSubConst(t *testing.T) {
486         x1 := sub1_ssa()
487         want1 := uint64(6)
488         if x1 != want1 {
489                 t.Errorf("sub1_ssa()=%d, got %d", want1, x1)
490         }
491         x2 := sub2_ssa()
492         want2 := uint8(251)
493         if x2 != want2 {
494                 t.Errorf("sub2_ssa()=%d, got %d", want2, x2)
495         }
496 }
497
498 //go:noinline
499 func orPhi_ssa(a bool, x int) int {
500         v := 0
501         if a {
502                 v = -1
503         } else {
504                 v = -1
505         }
506         return x | v
507 }
508
509 func testOrPhi(t *testing.T) {
510         if want, got := -1, orPhi_ssa(true, 4); got != want {
511                 t.Errorf("orPhi_ssa(true, 4)=%d, want %d", got, want)
512         }
513         if want, got := -1, orPhi_ssa(false, 0); got != want {
514                 t.Errorf("orPhi_ssa(false, 0)=%d, want %d", got, want)
515         }
516 }
517
518 //go:noinline
519 func addshiftLL_ssa(a, b uint32) uint32 {
520         return a + b<<3
521 }
522
523 //go:noinline
524 func subshiftLL_ssa(a, b uint32) uint32 {
525         return a - b<<3
526 }
527
528 //go:noinline
529 func rsbshiftLL_ssa(a, b uint32) uint32 {
530         return a<<3 - b
531 }
532
533 //go:noinline
534 func andshiftLL_ssa(a, b uint32) uint32 {
535         return a & (b << 3)
536 }
537
538 //go:noinline
539 func orshiftLL_ssa(a, b uint32) uint32 {
540         return a | b<<3
541 }
542
543 //go:noinline
544 func xorshiftLL_ssa(a, b uint32) uint32 {
545         return a ^ b<<3
546 }
547
548 //go:noinline
549 func bicshiftLL_ssa(a, b uint32) uint32 {
550         return a &^ (b << 3)
551 }
552
553 //go:noinline
554 func notshiftLL_ssa(a uint32) uint32 {
555         return ^(a << 3)
556 }
557
558 //go:noinline
559 func addshiftRL_ssa(a, b uint32) uint32 {
560         return a + b>>3
561 }
562
563 //go:noinline
564 func subshiftRL_ssa(a, b uint32) uint32 {
565         return a - b>>3
566 }
567
568 //go:noinline
569 func rsbshiftRL_ssa(a, b uint32) uint32 {
570         return a>>3 - b
571 }
572
573 //go:noinline
574 func andshiftRL_ssa(a, b uint32) uint32 {
575         return a & (b >> 3)
576 }
577
578 //go:noinline
579 func orshiftRL_ssa(a, b uint32) uint32 {
580         return a | b>>3
581 }
582
583 //go:noinline
584 func xorshiftRL_ssa(a, b uint32) uint32 {
585         return a ^ b>>3
586 }
587
588 //go:noinline
589 func bicshiftRL_ssa(a, b uint32) uint32 {
590         return a &^ (b >> 3)
591 }
592
593 //go:noinline
594 func notshiftRL_ssa(a uint32) uint32 {
595         return ^(a >> 3)
596 }
597
598 //go:noinline
599 func addshiftRA_ssa(a, b int32) int32 {
600         return a + b>>3
601 }
602
603 //go:noinline
604 func subshiftRA_ssa(a, b int32) int32 {
605         return a - b>>3
606 }
607
608 //go:noinline
609 func rsbshiftRA_ssa(a, b int32) int32 {
610         return a>>3 - b
611 }
612
613 //go:noinline
614 func andshiftRA_ssa(a, b int32) int32 {
615         return a & (b >> 3)
616 }
617
618 //go:noinline
619 func orshiftRA_ssa(a, b int32) int32 {
620         return a | b>>3
621 }
622
623 //go:noinline
624 func xorshiftRA_ssa(a, b int32) int32 {
625         return a ^ b>>3
626 }
627
628 //go:noinline
629 func bicshiftRA_ssa(a, b int32) int32 {
630         return a &^ (b >> 3)
631 }
632
633 //go:noinline
634 func notshiftRA_ssa(a int32) int32 {
635         return ^(a >> 3)
636 }
637
638 //go:noinline
639 func addshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
640         return a + b<<s
641 }
642
643 //go:noinline
644 func subshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
645         return a - b<<s
646 }
647
648 //go:noinline
649 func rsbshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
650         return a<<s - b
651 }
652
653 //go:noinline
654 func andshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
655         return a & (b << s)
656 }
657
658 //go:noinline
659 func orshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
660         return a | b<<s
661 }
662
663 //go:noinline
664 func xorshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
665         return a ^ b<<s
666 }
667
668 //go:noinline
669 func bicshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
670         return a &^ (b << s)
671 }
672
673 //go:noinline
674 func notshiftLLreg_ssa(a uint32, s uint8) uint32 {
675         return ^(a << s)
676 }
677
678 //go:noinline
679 func addshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
680         return a + b>>s
681 }
682
683 //go:noinline
684 func subshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
685         return a - b>>s
686 }
687
688 //go:noinline
689 func rsbshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
690         return a>>s - b
691 }
692
693 //go:noinline
694 func andshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
695         return a & (b >> s)
696 }
697
698 //go:noinline
699 func orshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
700         return a | b>>s
701 }
702
703 //go:noinline
704 func xorshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
705         return a ^ b>>s
706 }
707
708 //go:noinline
709 func bicshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
710         return a &^ (b >> s)
711 }
712
713 //go:noinline
714 func notshiftRLreg_ssa(a uint32, s uint8) uint32 {
715         return ^(a >> s)
716 }
717
718 //go:noinline
719 func addshiftRAreg_ssa(a, b int32, s uint8) int32 {
720         return a + b>>s
721 }
722
723 //go:noinline
724 func subshiftRAreg_ssa(a, b int32, s uint8) int32 {
725         return a - b>>s
726 }
727
728 //go:noinline
729 func rsbshiftRAreg_ssa(a, b int32, s uint8) int32 {
730         return a>>s - b
731 }
732
733 //go:noinline
734 func andshiftRAreg_ssa(a, b int32, s uint8) int32 {
735         return a & (b >> s)
736 }
737
738 //go:noinline
739 func orshiftRAreg_ssa(a, b int32, s uint8) int32 {
740         return a | b>>s
741 }
742
743 //go:noinline
744 func xorshiftRAreg_ssa(a, b int32, s uint8) int32 {
745         return a ^ b>>s
746 }
747
748 //go:noinline
749 func bicshiftRAreg_ssa(a, b int32, s uint8) int32 {
750         return a &^ (b >> s)
751 }
752
753 //go:noinline
754 func notshiftRAreg_ssa(a int32, s uint8) int32 {
755         return ^(a >> s)
756 }
757
758 // test ARM shifted ops
759 func testShiftedOps(t *testing.T) {
760         a, b := uint32(10), uint32(42)
761         if want, got := a+b<<3, addshiftLL_ssa(a, b); got != want {
762                 t.Errorf("addshiftLL_ssa(10, 42) = %d want %d", got, want)
763         }
764         if want, got := a-b<<3, subshiftLL_ssa(a, b); got != want {
765                 t.Errorf("subshiftLL_ssa(10, 42) = %d want %d", got, want)
766         }
767         if want, got := a<<3-b, rsbshiftLL_ssa(a, b); got != want {
768                 t.Errorf("rsbshiftLL_ssa(10, 42) = %d want %d", got, want)
769         }
770         if want, got := a&(b<<3), andshiftLL_ssa(a, b); got != want {
771                 t.Errorf("andshiftLL_ssa(10, 42) = %d want %d", got, want)
772         }
773         if want, got := a|b<<3, orshiftLL_ssa(a, b); got != want {
774                 t.Errorf("orshiftLL_ssa(10, 42) = %d want %d", got, want)
775         }
776         if want, got := a^b<<3, xorshiftLL_ssa(a, b); got != want {
777                 t.Errorf("xorshiftLL_ssa(10, 42) = %d want %d", got, want)
778         }
779         if want, got := a&^(b<<3), bicshiftLL_ssa(a, b); got != want {
780                 t.Errorf("bicshiftLL_ssa(10, 42) = %d want %d", got, want)
781         }
782         if want, got := ^(a << 3), notshiftLL_ssa(a); got != want {
783                 t.Errorf("notshiftLL_ssa(10) = %d want %d", got, want)
784         }
785         if want, got := a+b>>3, addshiftRL_ssa(a, b); got != want {
786                 t.Errorf("addshiftRL_ssa(10, 42) = %d want %d", got, want)
787         }
788         if want, got := a-b>>3, subshiftRL_ssa(a, b); got != want {
789                 t.Errorf("subshiftRL_ssa(10, 42) = %d want %d", got, want)
790         }
791         if want, got := a>>3-b, rsbshiftRL_ssa(a, b); got != want {
792                 t.Errorf("rsbshiftRL_ssa(10, 42) = %d want %d", got, want)
793         }
794         if want, got := a&(b>>3), andshiftRL_ssa(a, b); got != want {
795                 t.Errorf("andshiftRL_ssa(10, 42) = %d want %d", got, want)
796         }
797         if want, got := a|b>>3, orshiftRL_ssa(a, b); got != want {
798                 t.Errorf("orshiftRL_ssa(10, 42) = %d want %d", got, want)
799         }
800         if want, got := a^b>>3, xorshiftRL_ssa(a, b); got != want {
801                 t.Errorf("xorshiftRL_ssa(10, 42) = %d want %d", got, want)
802         }
803         if want, got := a&^(b>>3), bicshiftRL_ssa(a, b); got != want {
804                 t.Errorf("bicshiftRL_ssa(10, 42) = %d want %d", got, want)
805         }
806         if want, got := ^(a >> 3), notshiftRL_ssa(a); got != want {
807                 t.Errorf("notshiftRL_ssa(10) = %d want %d", got, want)
808         }
809         c, d := int32(10), int32(-42)
810         if want, got := c+d>>3, addshiftRA_ssa(c, d); got != want {
811                 t.Errorf("addshiftRA_ssa(10, -42) = %d want %d", got, want)
812         }
813         if want, got := c-d>>3, subshiftRA_ssa(c, d); got != want {
814                 t.Errorf("subshiftRA_ssa(10, -42) = %d want %d", got, want)
815         }
816         if want, got := c>>3-d, rsbshiftRA_ssa(c, d); got != want {
817                 t.Errorf("rsbshiftRA_ssa(10, -42) = %d want %d", got, want)
818         }
819         if want, got := c&(d>>3), andshiftRA_ssa(c, d); got != want {
820                 t.Errorf("andshiftRA_ssa(10, -42) = %d want %d", got, want)
821         }
822         if want, got := c|d>>3, orshiftRA_ssa(c, d); got != want {
823                 t.Errorf("orshiftRA_ssa(10, -42) = %d want %d", got, want)
824         }
825         if want, got := c^d>>3, xorshiftRA_ssa(c, d); got != want {
826                 t.Errorf("xorshiftRA_ssa(10, -42) = %d want %d", got, want)
827         }
828         if want, got := c&^(d>>3), bicshiftRA_ssa(c, d); got != want {
829                 t.Errorf("bicshiftRA_ssa(10, -42) = %d want %d", got, want)
830         }
831         if want, got := ^(d >> 3), notshiftRA_ssa(d); got != want {
832                 t.Errorf("notshiftRA_ssa(-42) = %d want %d", got, want)
833         }
834         s := uint8(3)
835         if want, got := a+b<<s, addshiftLLreg_ssa(a, b, s); got != want {
836                 t.Errorf("addshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
837         }
838         if want, got := a-b<<s, subshiftLLreg_ssa(a, b, s); got != want {
839                 t.Errorf("subshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
840         }
841         if want, got := a<<s-b, rsbshiftLLreg_ssa(a, b, s); got != want {
842                 t.Errorf("rsbshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
843         }
844         if want, got := a&(b<<s), andshiftLLreg_ssa(a, b, s); got != want {
845                 t.Errorf("andshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
846         }
847         if want, got := a|b<<s, orshiftLLreg_ssa(a, b, s); got != want {
848                 t.Errorf("orshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
849         }
850         if want, got := a^b<<s, xorshiftLLreg_ssa(a, b, s); got != want {
851                 t.Errorf("xorshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
852         }
853         if want, got := a&^(b<<s), bicshiftLLreg_ssa(a, b, s); got != want {
854                 t.Errorf("bicshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
855         }
856         if want, got := ^(a << s), notshiftLLreg_ssa(a, s); got != want {
857                 t.Errorf("notshiftLLreg_ssa(10) = %d want %d", got, want)
858         }
859         if want, got := a+b>>s, addshiftRLreg_ssa(a, b, s); got != want {
860                 t.Errorf("addshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
861         }
862         if want, got := a-b>>s, subshiftRLreg_ssa(a, b, s); got != want {
863                 t.Errorf("subshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
864         }
865         if want, got := a>>s-b, rsbshiftRLreg_ssa(a, b, s); got != want {
866                 t.Errorf("rsbshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
867         }
868         if want, got := a&(b>>s), andshiftRLreg_ssa(a, b, s); got != want {
869                 t.Errorf("andshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
870         }
871         if want, got := a|b>>s, orshiftRLreg_ssa(a, b, s); got != want {
872                 t.Errorf("orshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
873         }
874         if want, got := a^b>>s, xorshiftRLreg_ssa(a, b, s); got != want {
875                 t.Errorf("xorshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
876         }
877         if want, got := a&^(b>>s), bicshiftRLreg_ssa(a, b, s); got != want {
878                 t.Errorf("bicshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
879         }
880         if want, got := ^(a >> s), notshiftRLreg_ssa(a, s); got != want {
881                 t.Errorf("notshiftRLreg_ssa(10) = %d want %d", got, want)
882         }
883         if want, got := c+d>>s, addshiftRAreg_ssa(c, d, s); got != want {
884                 t.Errorf("addshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
885         }
886         if want, got := c-d>>s, subshiftRAreg_ssa(c, d, s); got != want {
887                 t.Errorf("subshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
888         }
889         if want, got := c>>s-d, rsbshiftRAreg_ssa(c, d, s); got != want {
890                 t.Errorf("rsbshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
891         }
892         if want, got := c&(d>>s), andshiftRAreg_ssa(c, d, s); got != want {
893                 t.Errorf("andshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
894         }
895         if want, got := c|d>>s, orshiftRAreg_ssa(c, d, s); got != want {
896                 t.Errorf("orshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
897         }
898         if want, got := c^d>>s, xorshiftRAreg_ssa(c, d, s); got != want {
899                 t.Errorf("xorshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
900         }
901         if want, got := c&^(d>>s), bicshiftRAreg_ssa(c, d, s); got != want {
902                 t.Errorf("bicshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
903         }
904         if want, got := ^(d >> s), notshiftRAreg_ssa(d, s); got != want {
905                 t.Errorf("notshiftRAreg_ssa(-42, 3) = %d want %d", got, want)
906         }
907 }
908
909 // TestArithmetic tests that both backends have the same result for arithmetic expressions.
910 func TestArithmetic(t *testing.T) {
911         test64BitConstMult(t)
912         test64BitConstAdd(t)
913         testRegallocCVSpill(t)
914         testSubqToNegq(t)
915         testBitwiseLogic(t)
916         testOcom(t)
917         testLrot(t)
918         testShiftCX(t)
919         testSubConst(t)
920         testOverflowConstShift(t)
921         testArithConstShift(t)
922         testArithRshConst(t)
923         testLargeConst(t)
924         testLoadCombine(t)
925         testLoadSymCombine(t)
926         testShiftRemoval(t)
927         testShiftedOps(t)
928         testDivFixUp(t)
929         testDivisibleSignedPow2(t)
930         testDivisibility(t)
931 }
932
933 // testDivFixUp ensures that signed division fix-ups are being generated.
934 func testDivFixUp(t *testing.T) {
935         defer func() {
936                 if r := recover(); r != nil {
937                         t.Error("testDivFixUp failed")
938                         if e, ok := r.(runtime.Error); ok {
939                                 t.Logf("%v\n", e.Error())
940                         }
941                 }
942         }()
943         var w int8 = -128
944         var x int16 = -32768
945         var y int32 = -2147483648
946         var z int64 = -9223372036854775808
947
948         for i := -5; i < 0; i++ {
949                 g8 = w / int8(i)
950                 g16 = x / int16(i)
951                 g32 = y / int32(i)
952                 g64 = z / int64(i)
953                 g8 = w % int8(i)
954                 g16 = x % int16(i)
955                 g32 = y % int32(i)
956                 g64 = z % int64(i)
957         }
958 }
959
960 //go:noinline
961 func divisible_int8_2to1(x int8) bool {
962         return x%(1<<1) == 0
963 }
964
965 //go:noinline
966 func divisible_int8_2to2(x int8) bool {
967         return x%(1<<2) == 0
968 }
969
970 //go:noinline
971 func divisible_int8_2to3(x int8) bool {
972         return x%(1<<3) == 0
973 }
974
975 //go:noinline
976 func divisible_int8_2to4(x int8) bool {
977         return x%(1<<4) == 0
978 }
979
980 //go:noinline
981 func divisible_int8_2to5(x int8) bool {
982         return x%(1<<5) == 0
983 }
984
985 //go:noinline
986 func divisible_int8_2to6(x int8) bool {
987         return x%(1<<6) == 0
988 }
989
990 //go:noinline
991 func divisible_int16_2to1(x int16) bool {
992         return x%(1<<1) == 0
993 }
994
995 //go:noinline
996 func divisible_int16_2to2(x int16) bool {
997         return x%(1<<2) == 0
998 }
999
1000 //go:noinline
1001 func divisible_int16_2to3(x int16) bool {
1002         return x%(1<<3) == 0
1003 }
1004
1005 //go:noinline
1006 func divisible_int16_2to4(x int16) bool {
1007         return x%(1<<4) == 0
1008 }
1009
1010 //go:noinline
1011 func divisible_int16_2to5(x int16) bool {
1012         return x%(1<<5) == 0
1013 }
1014
1015 //go:noinline
1016 func divisible_int16_2to6(x int16) bool {
1017         return x%(1<<6) == 0
1018 }
1019
1020 //go:noinline
1021 func divisible_int16_2to7(x int16) bool {
1022         return x%(1<<7) == 0
1023 }
1024
1025 //go:noinline
1026 func divisible_int16_2to8(x int16) bool {
1027         return x%(1<<8) == 0
1028 }
1029
1030 //go:noinline
1031 func divisible_int16_2to9(x int16) bool {
1032         return x%(1<<9) == 0
1033 }
1034
1035 //go:noinline
1036 func divisible_int16_2to10(x int16) bool {
1037         return x%(1<<10) == 0
1038 }
1039
1040 //go:noinline
1041 func divisible_int16_2to11(x int16) bool {
1042         return x%(1<<11) == 0
1043 }
1044
1045 //go:noinline
1046 func divisible_int16_2to12(x int16) bool {
1047         return x%(1<<12) == 0
1048 }
1049
1050 //go:noinline
1051 func divisible_int16_2to13(x int16) bool {
1052         return x%(1<<13) == 0
1053 }
1054
1055 //go:noinline
1056 func divisible_int16_2to14(x int16) bool {
1057         return x%(1<<14) == 0
1058 }
1059
1060 //go:noinline
1061 func divisible_int32_2to4(x int32) bool {
1062         return x%(1<<4) == 0
1063 }
1064
1065 //go:noinline
1066 func divisible_int32_2to15(x int32) bool {
1067         return x%(1<<15) == 0
1068 }
1069
1070 //go:noinline
1071 func divisible_int32_2to26(x int32) bool {
1072         return x%(1<<26) == 0
1073 }
1074
1075 //go:noinline
1076 func divisible_int64_2to4(x int64) bool {
1077         return x%(1<<4) == 0
1078 }
1079
1080 //go:noinline
1081 func divisible_int64_2to15(x int64) bool {
1082         return x%(1<<15) == 0
1083 }
1084
1085 //go:noinline
1086 func divisible_int64_2to26(x int64) bool {
1087         return x%(1<<26) == 0
1088 }
1089
1090 //go:noinline
1091 func divisible_int64_2to34(x int64) bool {
1092         return x%(1<<34) == 0
1093 }
1094
1095 //go:noinline
1096 func divisible_int64_2to48(x int64) bool {
1097         return x%(1<<48) == 0
1098 }
1099
1100 //go:noinline
1101 func divisible_int64_2to57(x int64) bool {
1102         return x%(1<<57) == 0
1103 }
1104
1105 // testDivisibleSignedPow2 confirms that x%(1<<k)==0 is rewritten correctly
1106 func testDivisibleSignedPow2(t *testing.T) {
1107         var i int64
1108         var pow2 = []int64{
1109                 1,
1110                 1 << 1,
1111                 1 << 2,
1112                 1 << 3,
1113                 1 << 4,
1114                 1 << 5,
1115                 1 << 6,
1116                 1 << 7,
1117                 1 << 8,
1118                 1 << 9,
1119                 1 << 10,
1120                 1 << 11,
1121                 1 << 12,
1122                 1 << 13,
1123                 1 << 14,
1124         }
1125         // exhaustive test for int8
1126         for i = math.MinInt8; i <= math.MaxInt8; i++ {
1127                 if want, got := int8(i)%int8(pow2[1]) == 0, divisible_int8_2to1(int8(i)); got != want {
1128                         t.Errorf("divisible_int8_2to1(%d) = %v want %v", i, got, want)
1129                 }
1130                 if want, got := int8(i)%int8(pow2[2]) == 0, divisible_int8_2to2(int8(i)); got != want {
1131                         t.Errorf("divisible_int8_2to2(%d) = %v want %v", i, got, want)
1132                 }
1133                 if want, got := int8(i)%int8(pow2[3]) == 0, divisible_int8_2to3(int8(i)); got != want {
1134                         t.Errorf("divisible_int8_2to3(%d) = %v want %v", i, got, want)
1135                 }
1136                 if want, got := int8(i)%int8(pow2[4]) == 0, divisible_int8_2to4(int8(i)); got != want {
1137                         t.Errorf("divisible_int8_2to4(%d) = %v want %v", i, got, want)
1138                 }
1139                 if want, got := int8(i)%int8(pow2[5]) == 0, divisible_int8_2to5(int8(i)); got != want {
1140                         t.Errorf("divisible_int8_2to5(%d) = %v want %v", i, got, want)
1141                 }
1142                 if want, got := int8(i)%int8(pow2[6]) == 0, divisible_int8_2to6(int8(i)); got != want {
1143                         t.Errorf("divisible_int8_2to6(%d) = %v want %v", i, got, want)
1144                 }
1145         }
1146         // exhaustive test for int16
1147         for i = math.MinInt16; i <= math.MaxInt16; i++ {
1148                 if want, got := int16(i)%int16(pow2[1]) == 0, divisible_int16_2to1(int16(i)); got != want {
1149                         t.Errorf("divisible_int16_2to1(%d) = %v want %v", i, got, want)
1150                 }
1151                 if want, got := int16(i)%int16(pow2[2]) == 0, divisible_int16_2to2(int16(i)); got != want {
1152                         t.Errorf("divisible_int16_2to2(%d) = %v want %v", i, got, want)
1153                 }
1154                 if want, got := int16(i)%int16(pow2[3]) == 0, divisible_int16_2to3(int16(i)); got != want {
1155                         t.Errorf("divisible_int16_2to3(%d) = %v want %v", i, got, want)
1156                 }
1157                 if want, got := int16(i)%int16(pow2[4]) == 0, divisible_int16_2to4(int16(i)); got != want {
1158                         t.Errorf("divisible_int16_2to4(%d) = %v want %v", i, got, want)
1159                 }
1160                 if want, got := int16(i)%int16(pow2[5]) == 0, divisible_int16_2to5(int16(i)); got != want {
1161                         t.Errorf("divisible_int16_2to5(%d) = %v want %v", i, got, want)
1162                 }
1163                 if want, got := int16(i)%int16(pow2[6]) == 0, divisible_int16_2to6(int16(i)); got != want {
1164                         t.Errorf("divisible_int16_2to6(%d) = %v want %v", i, got, want)
1165                 }
1166                 if want, got := int16(i)%int16(pow2[7]) == 0, divisible_int16_2to7(int16(i)); got != want {
1167                         t.Errorf("divisible_int16_2to7(%d) = %v want %v", i, got, want)
1168                 }
1169                 if want, got := int16(i)%int16(pow2[8]) == 0, divisible_int16_2to8(int16(i)); got != want {
1170                         t.Errorf("divisible_int16_2to8(%d) = %v want %v", i, got, want)
1171                 }
1172                 if want, got := int16(i)%int16(pow2[9]) == 0, divisible_int16_2to9(int16(i)); got != want {
1173                         t.Errorf("divisible_int16_2to9(%d) = %v want %v", i, got, want)
1174                 }
1175                 if want, got := int16(i)%int16(pow2[10]) == 0, divisible_int16_2to10(int16(i)); got != want {
1176                         t.Errorf("divisible_int16_2to10(%d) = %v want %v", i, got, want)
1177                 }
1178                 if want, got := int16(i)%int16(pow2[11]) == 0, divisible_int16_2to11(int16(i)); got != want {
1179                         t.Errorf("divisible_int16_2to11(%d) = %v want %v", i, got, want)
1180                 }
1181                 if want, got := int16(i)%int16(pow2[12]) == 0, divisible_int16_2to12(int16(i)); got != want {
1182                         t.Errorf("divisible_int16_2to12(%d) = %v want %v", i, got, want)
1183                 }
1184                 if want, got := int16(i)%int16(pow2[13]) == 0, divisible_int16_2to13(int16(i)); got != want {
1185                         t.Errorf("divisible_int16_2to13(%d) = %v want %v", i, got, want)
1186                 }
1187                 if want, got := int16(i)%int16(pow2[14]) == 0, divisible_int16_2to14(int16(i)); got != want {
1188                         t.Errorf("divisible_int16_2to14(%d) = %v want %v", i, got, want)
1189                 }
1190         }
1191         // spot check for int32 and int64
1192         var (
1193                 two4  int64 = 1 << 4
1194                 two15 int64 = 1 << 15
1195                 two26 int64 = 1 << 26
1196                 two34 int64 = 1 << 34
1197                 two48 int64 = 1 << 48
1198                 two57 int64 = 1 << 57
1199         )
1200         var xs = []int64{two4, two4 + 3, -3 * two4, -3*two4 + 1,
1201                 two15, two15 + 3, -3 * two15, -3*two15 + 1,
1202                 two26, two26 + 37, -5 * two26, -5*two26 + 2,
1203                 two34, two34 + 356, -7 * two34, -7*two34 + 13,
1204                 two48, two48 + 3000, -12 * two48, -12*two48 + 1111,
1205                 two57, two57 + 397654, -15 * two57, -15*two57 + 11234,
1206         }
1207         for _, x := range xs {
1208                 if int64(int32(x)) == x {
1209                         if want, got := int32(x)%int32(two4) == 0, divisible_int32_2to4(int32(x)); got != want {
1210                                 t.Errorf("divisible_int32_2to4(%d) = %v want %v", x, got, want)
1211                         }
1212
1213                         if want, got := int32(x)%int32(two15) == 0, divisible_int32_2to15(int32(x)); got != want {
1214                                 t.Errorf("divisible_int32_2to15(%d) = %v want %v", x, got, want)
1215                         }
1216
1217                         if want, got := int32(x)%int32(two26) == 0, divisible_int32_2to26(int32(x)); got != want {
1218                                 t.Errorf("divisible_int32_2to26(%d) = %v want %v", x, got, want)
1219                         }
1220                 }
1221                 // spot check for int64
1222                 if want, got := x%two4 == 0, divisible_int64_2to4(x); got != want {
1223                         t.Errorf("divisible_int64_2to4(%d) = %v want %v", x, got, want)
1224                 }
1225
1226                 if want, got := x%two15 == 0, divisible_int64_2to15(x); got != want {
1227                         t.Errorf("divisible_int64_2to15(%d) = %v want %v", x, got, want)
1228                 }
1229
1230                 if want, got := x%two26 == 0, divisible_int64_2to26(x); got != want {
1231                         t.Errorf("divisible_int64_2to26(%d) = %v want %v", x, got, want)
1232                 }
1233
1234                 if want, got := x%two34 == 0, divisible_int64_2to34(x); got != want {
1235                         t.Errorf("divisible_int64_2to34(%d) = %v want %v", x, got, want)
1236                 }
1237
1238                 if want, got := x%two48 == 0, divisible_int64_2to48(x); got != want {
1239                         t.Errorf("divisible_int64_2to48(%d) = %v want %v", x, got, want)
1240                 }
1241
1242                 if want, got := x%two57 == 0, divisible_int64_2to57(x); got != want {
1243                         t.Errorf("divisible_int64_2to57(%d) = %v want %v", x, got, want)
1244                 }
1245         }
1246 }
1247
1248 func div6_uint8(n uint8) bool {
1249         return n%6 == 0
1250 }
1251
1252 //go:noinline
1253 func div6_uint16(n uint16) bool {
1254         return n%6 == 0
1255 }
1256
1257 //go:noinline
1258 func div6_uint32(n uint32) bool {
1259         return n%6 == 0
1260 }
1261
1262 //go:noinline
1263 func div6_uint64(n uint64) bool {
1264         return n%6 == 0
1265 }
1266
1267 //go:noinline
1268 func div19_uint8(n uint8) bool {
1269         return n%19 == 0
1270 }
1271
1272 //go:noinline
1273 func div19_uint16(n uint16) bool {
1274         return n%19 == 0
1275 }
1276
1277 //go:noinline
1278 func div19_uint32(n uint32) bool {
1279         return n%19 == 0
1280 }
1281
1282 //go:noinline
1283 func div19_uint64(n uint64) bool {
1284         return n%19 == 0
1285 }
1286
1287 //go:noinline
1288 func div6_int8(n int8) bool {
1289         return n%6 == 0
1290 }
1291
1292 //go:noinline
1293 func div6_int16(n int16) bool {
1294         return n%6 == 0
1295 }
1296
1297 //go:noinline
1298 func div6_int32(n int32) bool {
1299         return n%6 == 0
1300 }
1301
1302 //go:noinline
1303 func div6_int64(n int64) bool {
1304         return n%6 == 0
1305 }
1306
1307 //go:noinline
1308 func div19_int8(n int8) bool {
1309         return n%19 == 0
1310 }
1311
1312 //go:noinline
1313 func div19_int16(n int16) bool {
1314         return n%19 == 0
1315 }
1316
1317 //go:noinline
1318 func div19_int32(n int32) bool {
1319         return n%19 == 0
1320 }
1321
1322 //go:noinline
1323 func div19_int64(n int64) bool {
1324         return n%19 == 0
1325 }
1326
1327 // testDivisibility confirms that rewrite rules x%c ==0 for c constant are correct.
1328 func testDivisibility(t *testing.T) {
1329         // unsigned tests
1330         // test an even and an odd divisor
1331         var sixU, nineteenU uint64 = 6, 19
1332         // test all inputs for uint8, uint16
1333         for i := uint64(0); i <= math.MaxUint16; i++ {
1334                 if i <= math.MaxUint8 {
1335                         if want, got := uint8(i)%uint8(sixU) == 0, div6_uint8(uint8(i)); got != want {
1336                                 t.Errorf("div6_uint8(%d) = %v want %v", i, got, want)
1337                         }
1338                         if want, got := uint8(i)%uint8(nineteenU) == 0, div19_uint8(uint8(i)); got != want {
1339                                 t.Errorf("div6_uint19(%d) = %v want %v", i, got, want)
1340                         }
1341                 }
1342                 if want, got := uint16(i)%uint16(sixU) == 0, div6_uint16(uint16(i)); got != want {
1343                         t.Errorf("div6_uint16(%d) = %v want %v", i, got, want)
1344                 }
1345                 if want, got := uint16(i)%uint16(nineteenU) == 0, div19_uint16(uint16(i)); got != want {
1346                         t.Errorf("div19_uint16(%d) = %v want %v", i, got, want)
1347                 }
1348         }
1349         var maxU32, maxU64 uint64 = math.MaxUint32, math.MaxUint64
1350         // spot check inputs for uint32 and uint64
1351         xu := []uint64{
1352                 0, 1, 2, 3, 4, 5,
1353                 sixU, 2 * sixU, 3 * sixU, 5 * sixU, 12345 * sixU,
1354                 sixU + 1, 2*sixU - 5, 3*sixU + 3, 5*sixU + 4, 12345*sixU - 2,
1355                 nineteenU, 2 * nineteenU, 3 * nineteenU, 5 * nineteenU, 12345 * nineteenU,
1356                 nineteenU + 1, 2*nineteenU - 5, 3*nineteenU + 3, 5*nineteenU + 4, 12345*nineteenU - 2,
1357                 maxU32, maxU32 - 1, maxU32 - 2, maxU32 - 3, maxU32 - 4,
1358                 maxU32 - 5, maxU32 - 6, maxU32 - 7, maxU32 - 8,
1359                 maxU32 - 9, maxU32 - 10, maxU32 - 11, maxU32 - 12,
1360                 maxU32 - 13, maxU32 - 14, maxU32 - 15, maxU32 - 16,
1361                 maxU32 - 17, maxU32 - 18, maxU32 - 19, maxU32 - 20,
1362                 maxU64, maxU64 - 1, maxU64 - 2, maxU64 - 3, maxU64 - 4,
1363                 maxU64 - 5, maxU64 - 6, maxU64 - 7, maxU64 - 8,
1364                 maxU64 - 9, maxU64 - 10, maxU64 - 11, maxU64 - 12,
1365                 maxU64 - 13, maxU64 - 14, maxU64 - 15, maxU64 - 16,
1366                 maxU64 - 17, maxU64 - 18, maxU64 - 19, maxU64 - 20,
1367         }
1368         for _, x := range xu {
1369                 if x <= maxU32 {
1370                         if want, got := uint32(x)%uint32(sixU) == 0, div6_uint32(uint32(x)); got != want {
1371                                 t.Errorf("div6_uint32(%d) = %v want %v", x, got, want)
1372                         }
1373                         if want, got := uint32(x)%uint32(nineteenU) == 0, div19_uint32(uint32(x)); got != want {
1374                                 t.Errorf("div19_uint32(%d) = %v want %v", x, got, want)
1375                         }
1376                 }
1377                 if want, got := x%sixU == 0, div6_uint64(x); got != want {
1378                         t.Errorf("div6_uint64(%d) = %v want %v", x, got, want)
1379                 }
1380                 if want, got := x%nineteenU == 0, div19_uint64(x); got != want {
1381                         t.Errorf("div19_uint64(%d) = %v want %v", x, got, want)
1382                 }
1383         }
1384
1385         // signed tests
1386         // test an even and an odd divisor
1387         var sixS, nineteenS int64 = 6, 19
1388         // test all inputs for int8, int16
1389         for i := int64(math.MinInt16); i <= math.MaxInt16; i++ {
1390                 if math.MinInt8 <= i && i <= math.MaxInt8 {
1391                         if want, got := int8(i)%int8(sixS) == 0, div6_int8(int8(i)); got != want {
1392                                 t.Errorf("div6_int8(%d) = %v want %v", i, got, want)
1393                         }
1394                         if want, got := int8(i)%int8(nineteenS) == 0, div19_int8(int8(i)); got != want {
1395                                 t.Errorf("div6_int19(%d) = %v want %v", i, got, want)
1396                         }
1397                 }
1398                 if want, got := int16(i)%int16(sixS) == 0, div6_int16(int16(i)); got != want {
1399                         t.Errorf("div6_int16(%d) = %v want %v", i, got, want)
1400                 }
1401                 if want, got := int16(i)%int16(nineteenS) == 0, div19_int16(int16(i)); got != want {
1402                         t.Errorf("div19_int16(%d) = %v want %v", i, got, want)
1403                 }
1404         }
1405         var minI32, maxI32, minI64, maxI64 int64 = math.MinInt32, math.MaxInt32, math.MinInt64, math.MaxInt64
1406         // spot check inputs for int32 and int64
1407         xs := []int64{
1408                 0, 1, 2, 3, 4, 5,
1409                 -1, -2, -3, -4, -5,
1410                 sixS, 2 * sixS, 3 * sixS, 5 * sixS, 12345 * sixS,
1411                 sixS + 1, 2*sixS - 5, 3*sixS + 3, 5*sixS + 4, 12345*sixS - 2,
1412                 -sixS, -2 * sixS, -3 * sixS, -5 * sixS, -12345 * sixS,
1413                 -sixS + 1, -2*sixS - 5, -3*sixS + 3, -5*sixS + 4, -12345*sixS - 2,
1414                 nineteenS, 2 * nineteenS, 3 * nineteenS, 5 * nineteenS, 12345 * nineteenS,
1415                 nineteenS + 1, 2*nineteenS - 5, 3*nineteenS + 3, 5*nineteenS + 4, 12345*nineteenS - 2,
1416                 -nineteenS, -2 * nineteenS, -3 * nineteenS, -5 * nineteenS, -12345 * nineteenS,
1417                 -nineteenS + 1, -2*nineteenS - 5, -3*nineteenS + 3, -5*nineteenS + 4, -12345*nineteenS - 2,
1418                 minI32, minI32 + 1, minI32 + 2, minI32 + 3, minI32 + 4,
1419                 minI32 + 5, minI32 + 6, minI32 + 7, minI32 + 8,
1420                 minI32 + 9, minI32 + 10, minI32 + 11, minI32 + 12,
1421                 minI32 + 13, minI32 + 14, minI32 + 15, minI32 + 16,
1422                 minI32 + 17, minI32 + 18, minI32 + 19, minI32 + 20,
1423                 maxI32, maxI32 - 1, maxI32 - 2, maxI32 - 3, maxI32 - 4,
1424                 maxI32 - 5, maxI32 - 6, maxI32 - 7, maxI32 - 8,
1425                 maxI32 - 9, maxI32 - 10, maxI32 - 11, maxI32 - 12,
1426                 maxI32 - 13, maxI32 - 14, maxI32 - 15, maxI32 - 16,
1427                 maxI32 - 17, maxI32 - 18, maxI32 - 19, maxI32 - 20,
1428                 minI64, minI64 + 1, minI64 + 2, minI64 + 3, minI64 + 4,
1429                 minI64 + 5, minI64 + 6, minI64 + 7, minI64 + 8,
1430                 minI64 + 9, minI64 + 10, minI64 + 11, minI64 + 12,
1431                 minI64 + 13, minI64 + 14, minI64 + 15, minI64 + 16,
1432                 minI64 + 17, minI64 + 18, minI64 + 19, minI64 + 20,
1433                 maxI64, maxI64 - 1, maxI64 - 2, maxI64 - 3, maxI64 - 4,
1434                 maxI64 - 5, maxI64 - 6, maxI64 - 7, maxI64 - 8,
1435                 maxI64 - 9, maxI64 - 10, maxI64 - 11, maxI64 - 12,
1436                 maxI64 - 13, maxI64 - 14, maxI64 - 15, maxI64 - 16,
1437                 maxI64 - 17, maxI64 - 18, maxI64 - 19, maxI64 - 20,
1438         }
1439         for _, x := range xs {
1440                 if minI32 <= x && x <= maxI32 {
1441                         if want, got := int32(x)%int32(sixS) == 0, div6_int32(int32(x)); got != want {
1442                                 t.Errorf("div6_int32(%d) = %v want %v", x, got, want)
1443                         }
1444                         if want, got := int32(x)%int32(nineteenS) == 0, div19_int32(int32(x)); got != want {
1445                                 t.Errorf("div19_int32(%d) = %v want %v", x, got, want)
1446                         }
1447                 }
1448                 if want, got := x%sixS == 0, div6_int64(x); got != want {
1449                         t.Errorf("div6_int64(%d) = %v want %v", x, got, want)
1450                 }
1451                 if want, got := x%nineteenS == 0, div19_int64(x); got != want {
1452                         t.Errorf("div19_int64(%d) = %v want %v", x, got, want)
1453                 }
1454         }
1455 }
1456
1457 //go:noinline
1458 func genREV16_1(c uint64) uint64 {
1459         b := ((c & 0xff00ff00ff00ff00) >> 8) | ((c & 0x00ff00ff00ff00ff) << 8)
1460         return b
1461 }
1462
1463 //go:noinline
1464 func genREV16_2(c uint64) uint64 {
1465         b := ((c & 0xff00ff00) >> 8) | ((c & 0x00ff00ff) << 8)
1466         return b
1467 }
1468
1469 //go:noinline
1470 func genREV16W(c uint32) uint32 {
1471         b := ((c & 0xff00ff00) >> 8) | ((c & 0x00ff00ff) << 8)
1472         return b
1473 }
1474
1475 func TestREV16(t *testing.T) {
1476         x := uint64(0x8f7f6f5f4f3f2f1f)
1477         want1 := uint64(0x7f8f5f6f3f4f1f2f)
1478         want2 := uint64(0x3f4f1f2f)
1479
1480         got1 := genREV16_1(x)
1481         if got1 != want1 {
1482                 t.Errorf("genREV16_1(%#x) = %#x want %#x", x, got1, want1)
1483         }
1484         got2 := genREV16_2(x)
1485         if got2 != want2 {
1486                 t.Errorf("genREV16_2(%#x) = %#x want %#x", x, got2, want2)
1487         }
1488 }
1489
1490 func TestREV16W(t *testing.T) {
1491         x := uint32(0x4f3f2f1f)
1492         want := uint32(0x3f4f1f2f)
1493
1494         got := genREV16W(x)
1495         if got != want {
1496                 t.Errorf("genREV16W(%#x) = %#x want %#x", x, got, want)
1497         }
1498 }