Home | History | Annotate | Download | only in gc
      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 package gc
      6 
      7 import (
      8 	"reflect"
      9 	"testing"
     10 )
     11 
     12 // Tests shifts of zero.
     13 
     14 //go:noinline
     15 func ofz64l64(n uint64) int64 {
     16 	var x int64
     17 	return x << n
     18 }
     19 
     20 //go:noinline
     21 func ofz64l32(n uint32) int64 {
     22 	var x int64
     23 	return x << n
     24 }
     25 
     26 //go:noinline
     27 func ofz64l16(n uint16) int64 {
     28 	var x int64
     29 	return x << n
     30 }
     31 
     32 //go:noinline
     33 func ofz64l8(n uint8) int64 {
     34 	var x int64
     35 	return x << n
     36 }
     37 
     38 //go:noinline
     39 func ofz64r64(n uint64) int64 {
     40 	var x int64
     41 	return x >> n
     42 }
     43 
     44 //go:noinline
     45 func ofz64r32(n uint32) int64 {
     46 	var x int64
     47 	return x >> n
     48 }
     49 
     50 //go:noinline
     51 func ofz64r16(n uint16) int64 {
     52 	var x int64
     53 	return x >> n
     54 }
     55 
     56 //go:noinline
     57 func ofz64r8(n uint8) int64 {
     58 	var x int64
     59 	return x >> n
     60 }
     61 
     62 //go:noinline
     63 func ofz64ur64(n uint64) uint64 {
     64 	var x uint64
     65 	return x >> n
     66 }
     67 
     68 //go:noinline
     69 func ofz64ur32(n uint32) uint64 {
     70 	var x uint64
     71 	return x >> n
     72 }
     73 
     74 //go:noinline
     75 func ofz64ur16(n uint16) uint64 {
     76 	var x uint64
     77 	return x >> n
     78 }
     79 
     80 //go:noinline
     81 func ofz64ur8(n uint8) uint64 {
     82 	var x uint64
     83 	return x >> n
     84 }
     85 
     86 //go:noinline
     87 func ofz32l64(n uint64) int32 {
     88 	var x int32
     89 	return x << n
     90 }
     91 
     92 //go:noinline
     93 func ofz32l32(n uint32) int32 {
     94 	var x int32
     95 	return x << n
     96 }
     97 
     98 //go:noinline
     99 func ofz32l16(n uint16) int32 {
    100 	var x int32
    101 	return x << n
    102 }
    103 
    104 //go:noinline
    105 func ofz32l8(n uint8) int32 {
    106 	var x int32
    107 	return x << n
    108 }
    109 
    110 //go:noinline
    111 func ofz32r64(n uint64) int32 {
    112 	var x int32
    113 	return x >> n
    114 }
    115 
    116 //go:noinline
    117 func ofz32r32(n uint32) int32 {
    118 	var x int32
    119 	return x >> n
    120 }
    121 
    122 //go:noinline
    123 func ofz32r16(n uint16) int32 {
    124 	var x int32
    125 	return x >> n
    126 }
    127 
    128 //go:noinline
    129 func ofz32r8(n uint8) int32 {
    130 	var x int32
    131 	return x >> n
    132 }
    133 
    134 //go:noinline
    135 func ofz32ur64(n uint64) uint32 {
    136 	var x uint32
    137 	return x >> n
    138 }
    139 
    140 //go:noinline
    141 func ofz32ur32(n uint32) uint32 {
    142 	var x uint32
    143 	return x >> n
    144 }
    145 
    146 //go:noinline
    147 func ofz32ur16(n uint16) uint32 {
    148 	var x uint32
    149 	return x >> n
    150 }
    151 
    152 //go:noinline
    153 func ofz32ur8(n uint8) uint32 {
    154 	var x uint32
    155 	return x >> n
    156 }
    157 
    158 //go:noinline
    159 func ofz16l64(n uint64) int16 {
    160 	var x int16
    161 	return x << n
    162 }
    163 
    164 //go:noinline
    165 func ofz16l32(n uint32) int16 {
    166 	var x int16
    167 	return x << n
    168 }
    169 
    170 //go:noinline
    171 func ofz16l16(n uint16) int16 {
    172 	var x int16
    173 	return x << n
    174 }
    175 
    176 //go:noinline
    177 func ofz16l8(n uint8) int16 {
    178 	var x int16
    179 	return x << n
    180 }
    181 
    182 //go:noinline
    183 func ofz16r64(n uint64) int16 {
    184 	var x int16
    185 	return x >> n
    186 }
    187 
    188 //go:noinline
    189 func ofz16r32(n uint32) int16 {
    190 	var x int16
    191 	return x >> n
    192 }
    193 
    194 //go:noinline
    195 func ofz16r16(n uint16) int16 {
    196 	var x int16
    197 	return x >> n
    198 }
    199 
    200 //go:noinline
    201 func ofz16r8(n uint8) int16 {
    202 	var x int16
    203 	return x >> n
    204 }
    205 
    206 //go:noinline
    207 func ofz16ur64(n uint64) uint16 {
    208 	var x uint16
    209 	return x >> n
    210 }
    211 
    212 //go:noinline
    213 func ofz16ur32(n uint32) uint16 {
    214 	var x uint16
    215 	return x >> n
    216 }
    217 
    218 //go:noinline
    219 func ofz16ur16(n uint16) uint16 {
    220 	var x uint16
    221 	return x >> n
    222 }
    223 
    224 //go:noinline
    225 func ofz16ur8(n uint8) uint16 {
    226 	var x uint16
    227 	return x >> n
    228 }
    229 
    230 //go:noinline
    231 func ofz8l64(n uint64) int8 {
    232 	var x int8
    233 	return x << n
    234 }
    235 
    236 //go:noinline
    237 func ofz8l32(n uint32) int8 {
    238 	var x int8
    239 	return x << n
    240 }
    241 
    242 //go:noinline
    243 func ofz8l16(n uint16) int8 {
    244 	var x int8
    245 	return x << n
    246 }
    247 
    248 //go:noinline
    249 func ofz8l8(n uint8) int8 {
    250 	var x int8
    251 	return x << n
    252 }
    253 
    254 //go:noinline
    255 func ofz8r64(n uint64) int8 {
    256 	var x int8
    257 	return x >> n
    258 }
    259 
    260 //go:noinline
    261 func ofz8r32(n uint32) int8 {
    262 	var x int8
    263 	return x >> n
    264 }
    265 
    266 //go:noinline
    267 func ofz8r16(n uint16) int8 {
    268 	var x int8
    269 	return x >> n
    270 }
    271 
    272 //go:noinline
    273 func ofz8r8(n uint8) int8 {
    274 	var x int8
    275 	return x >> n
    276 }
    277 
    278 //go:noinline
    279 func ofz8ur64(n uint64) uint8 {
    280 	var x uint8
    281 	return x >> n
    282 }
    283 
    284 //go:noinline
    285 func ofz8ur32(n uint32) uint8 {
    286 	var x uint8
    287 	return x >> n
    288 }
    289 
    290 //go:noinline
    291 func ofz8ur16(n uint16) uint8 {
    292 	var x uint8
    293 	return x >> n
    294 }
    295 
    296 //go:noinline
    297 func ofz8ur8(n uint8) uint8 {
    298 	var x uint8
    299 	return x >> n
    300 }
    301 
    302 func TestShiftOfZero(t *testing.T) {
    303 	if got := ofz64l64(5); got != 0 {
    304 		t.Errorf("0<<5 == %d, want 0", got)
    305 	}
    306 	if got := ofz64l32(5); got != 0 {
    307 		t.Errorf("0<<5 == %d, want 0", got)
    308 	}
    309 	if got := ofz64l16(5); got != 0 {
    310 		t.Errorf("0<<5 == %d, want 0", got)
    311 	}
    312 	if got := ofz64l8(5); got != 0 {
    313 		t.Errorf("0<<5 == %d, want 0", got)
    314 	}
    315 	if got := ofz64r64(5); got != 0 {
    316 		t.Errorf("0>>5 == %d, want 0", got)
    317 	}
    318 	if got := ofz64r32(5); got != 0 {
    319 		t.Errorf("0>>5 == %d, want 0", got)
    320 	}
    321 	if got := ofz64r16(5); got != 0 {
    322 		t.Errorf("0>>5 == %d, want 0", got)
    323 	}
    324 	if got := ofz64r8(5); got != 0 {
    325 		t.Errorf("0>>5 == %d, want 0", got)
    326 	}
    327 	if got := ofz64ur64(5); got != 0 {
    328 		t.Errorf("0>>>5 == %d, want 0", got)
    329 	}
    330 	if got := ofz64ur32(5); got != 0 {
    331 		t.Errorf("0>>>5 == %d, want 0", got)
    332 	}
    333 	if got := ofz64ur16(5); got != 0 {
    334 		t.Errorf("0>>>5 == %d, want 0", got)
    335 	}
    336 	if got := ofz64ur8(5); got != 0 {
    337 		t.Errorf("0>>>5 == %d, want 0", got)
    338 	}
    339 
    340 	if got := ofz32l64(5); got != 0 {
    341 		t.Errorf("0<<5 == %d, want 0", got)
    342 	}
    343 	if got := ofz32l32(5); got != 0 {
    344 		t.Errorf("0<<5 == %d, want 0", got)
    345 	}
    346 	if got := ofz32l16(5); got != 0 {
    347 		t.Errorf("0<<5 == %d, want 0", got)
    348 	}
    349 	if got := ofz32l8(5); got != 0 {
    350 		t.Errorf("0<<5 == %d, want 0", got)
    351 	}
    352 	if got := ofz32r64(5); got != 0 {
    353 		t.Errorf("0>>5 == %d, want 0", got)
    354 	}
    355 	if got := ofz32r32(5); got != 0 {
    356 		t.Errorf("0>>5 == %d, want 0", got)
    357 	}
    358 	if got := ofz32r16(5); got != 0 {
    359 		t.Errorf("0>>5 == %d, want 0", got)
    360 	}
    361 	if got := ofz32r8(5); got != 0 {
    362 		t.Errorf("0>>5 == %d, want 0", got)
    363 	}
    364 	if got := ofz32ur64(5); got != 0 {
    365 		t.Errorf("0>>>5 == %d, want 0", got)
    366 	}
    367 	if got := ofz32ur32(5); got != 0 {
    368 		t.Errorf("0>>>5 == %d, want 0", got)
    369 	}
    370 	if got := ofz32ur16(5); got != 0 {
    371 		t.Errorf("0>>>5 == %d, want 0", got)
    372 	}
    373 	if got := ofz32ur8(5); got != 0 {
    374 		t.Errorf("0>>>5 == %d, want 0", got)
    375 	}
    376 
    377 	if got := ofz16l64(5); got != 0 {
    378 		t.Errorf("0<<5 == %d, want 0", got)
    379 	}
    380 	if got := ofz16l32(5); got != 0 {
    381 		t.Errorf("0<<5 == %d, want 0", got)
    382 	}
    383 	if got := ofz16l16(5); got != 0 {
    384 		t.Errorf("0<<5 == %d, want 0", got)
    385 	}
    386 	if got := ofz16l8(5); got != 0 {
    387 		t.Errorf("0<<5 == %d, want 0", got)
    388 	}
    389 	if got := ofz16r64(5); got != 0 {
    390 		t.Errorf("0>>5 == %d, want 0", got)
    391 	}
    392 	if got := ofz16r32(5); got != 0 {
    393 		t.Errorf("0>>5 == %d, want 0", got)
    394 	}
    395 	if got := ofz16r16(5); got != 0 {
    396 		t.Errorf("0>>5 == %d, want 0", got)
    397 	}
    398 	if got := ofz16r8(5); got != 0 {
    399 		t.Errorf("0>>5 == %d, want 0", got)
    400 	}
    401 	if got := ofz16ur64(5); got != 0 {
    402 		t.Errorf("0>>>5 == %d, want 0", got)
    403 	}
    404 	if got := ofz16ur32(5); got != 0 {
    405 		t.Errorf("0>>>5 == %d, want 0", got)
    406 	}
    407 	if got := ofz16ur16(5); got != 0 {
    408 		t.Errorf("0>>>5 == %d, want 0", got)
    409 	}
    410 	if got := ofz16ur8(5); got != 0 {
    411 		t.Errorf("0>>>5 == %d, want 0", got)
    412 	}
    413 
    414 	if got := ofz8l64(5); got != 0 {
    415 		t.Errorf("0<<5 == %d, want 0", got)
    416 	}
    417 	if got := ofz8l32(5); got != 0 {
    418 		t.Errorf("0<<5 == %d, want 0", got)
    419 	}
    420 	if got := ofz8l16(5); got != 0 {
    421 		t.Errorf("0<<5 == %d, want 0", got)
    422 	}
    423 	if got := ofz8l8(5); got != 0 {
    424 		t.Errorf("0<<5 == %d, want 0", got)
    425 	}
    426 	if got := ofz8r64(5); got != 0 {
    427 		t.Errorf("0>>5 == %d, want 0", got)
    428 	}
    429 	if got := ofz8r32(5); got != 0 {
    430 		t.Errorf("0>>5 == %d, want 0", got)
    431 	}
    432 	if got := ofz8r16(5); got != 0 {
    433 		t.Errorf("0>>5 == %d, want 0", got)
    434 	}
    435 	if got := ofz8r8(5); got != 0 {
    436 		t.Errorf("0>>5 == %d, want 0", got)
    437 	}
    438 	if got := ofz8ur64(5); got != 0 {
    439 		t.Errorf("0>>>5 == %d, want 0", got)
    440 	}
    441 	if got := ofz8ur32(5); got != 0 {
    442 		t.Errorf("0>>>5 == %d, want 0", got)
    443 	}
    444 	if got := ofz8ur16(5); got != 0 {
    445 		t.Errorf("0>>>5 == %d, want 0", got)
    446 	}
    447 	if got := ofz8ur8(5); got != 0 {
    448 		t.Errorf("0>>>5 == %d, want 0", got)
    449 	}
    450 }
    451 
    452 //go:noinline
    453 func byz64l(n int64) int64 {
    454 	return n << 0
    455 }
    456 
    457 //go:noinline
    458 func byz64r(n int64) int64 {
    459 	return n >> 0
    460 }
    461 
    462 //go:noinline
    463 func byz64ur(n uint64) uint64 {
    464 	return n >> 0
    465 }
    466 
    467 //go:noinline
    468 func byz32l(n int32) int32 {
    469 	return n << 0
    470 }
    471 
    472 //go:noinline
    473 func byz32r(n int32) int32 {
    474 	return n >> 0
    475 }
    476 
    477 //go:noinline
    478 func byz32ur(n uint32) uint32 {
    479 	return n >> 0
    480 }
    481 
    482 //go:noinline
    483 func byz16l(n int16) int16 {
    484 	return n << 0
    485 }
    486 
    487 //go:noinline
    488 func byz16r(n int16) int16 {
    489 	return n >> 0
    490 }
    491 
    492 //go:noinline
    493 func byz16ur(n uint16) uint16 {
    494 	return n >> 0
    495 }
    496 
    497 //go:noinline
    498 func byz8l(n int8) int8 {
    499 	return n << 0
    500 }
    501 
    502 //go:noinline
    503 func byz8r(n int8) int8 {
    504 	return n >> 0
    505 }
    506 
    507 //go:noinline
    508 func byz8ur(n uint8) uint8 {
    509 	return n >> 0
    510 }
    511 
    512 func TestShiftByZero(t *testing.T) {
    513 	{
    514 		var n int64 = 0x5555555555555555
    515 		if got := byz64l(n); got != n {
    516 			t.Errorf("%x<<0 == %x, want %x", n, got, n)
    517 		}
    518 		if got := byz64r(n); got != n {
    519 			t.Errorf("%x>>0 == %x, want %x", n, got, n)
    520 		}
    521 	}
    522 	{
    523 		var n uint64 = 0xaaaaaaaaaaaaaaaa
    524 		if got := byz64ur(n); got != n {
    525 			t.Errorf("%x>>>0 == %x, want %x", n, got, n)
    526 		}
    527 	}
    528 
    529 	{
    530 		var n int32 = 0x55555555
    531 		if got := byz32l(n); got != n {
    532 			t.Errorf("%x<<0 == %x, want %x", n, got, n)
    533 		}
    534 		if got := byz32r(n); got != n {
    535 			t.Errorf("%x>>0 == %x, want %x", n, got, n)
    536 		}
    537 	}
    538 	{
    539 		var n uint32 = 0xaaaaaaaa
    540 		if got := byz32ur(n); got != n {
    541 			t.Errorf("%x>>>0 == %x, want %x", n, got, n)
    542 		}
    543 	}
    544 
    545 	{
    546 		var n int16 = 0x5555
    547 		if got := byz16l(n); got != n {
    548 			t.Errorf("%x<<0 == %x, want %x", n, got, n)
    549 		}
    550 		if got := byz16r(n); got != n {
    551 			t.Errorf("%x>>0 == %x, want %x", n, got, n)
    552 		}
    553 	}
    554 	{
    555 		var n uint16 = 0xaaaa
    556 		if got := byz16ur(n); got != n {
    557 			t.Errorf("%x>>>0 == %x, want %x", n, got, n)
    558 		}
    559 	}
    560 
    561 	{
    562 		var n int8 = 0x55
    563 		if got := byz8l(n); got != n {
    564 			t.Errorf("%x<<0 == %x, want %x", n, got, n)
    565 		}
    566 		if got := byz8r(n); got != n {
    567 			t.Errorf("%x>>0 == %x, want %x", n, got, n)
    568 		}
    569 	}
    570 	{
    571 		var n uint8 = 0x55
    572 		if got := byz8ur(n); got != n {
    573 			t.Errorf("%x>>>0 == %x, want %x", n, got, n)
    574 		}
    575 	}
    576 }
    577 
    578 //go:noinline
    579 func two64l(x int64) int64 {
    580 	return x << 1 << 1
    581 }
    582 
    583 //go:noinline
    584 func two64r(x int64) int64 {
    585 	return x >> 1 >> 1
    586 }
    587 
    588 //go:noinline
    589 func two64ur(x uint64) uint64 {
    590 	return x >> 1 >> 1
    591 }
    592 
    593 //go:noinline
    594 func two32l(x int32) int32 {
    595 	return x << 1 << 1
    596 }
    597 
    598 //go:noinline
    599 func two32r(x int32) int32 {
    600 	return x >> 1 >> 1
    601 }
    602 
    603 //go:noinline
    604 func two32ur(x uint32) uint32 {
    605 	return x >> 1 >> 1
    606 }
    607 
    608 //go:noinline
    609 func two16l(x int16) int16 {
    610 	return x << 1 << 1
    611 }
    612 
    613 //go:noinline
    614 func two16r(x int16) int16 {
    615 	return x >> 1 >> 1
    616 }
    617 
    618 //go:noinline
    619 func two16ur(x uint16) uint16 {
    620 	return x >> 1 >> 1
    621 }
    622 
    623 //go:noinline
    624 func two8l(x int8) int8 {
    625 	return x << 1 << 1
    626 }
    627 
    628 //go:noinline
    629 func two8r(x int8) int8 {
    630 	return x >> 1 >> 1
    631 }
    632 
    633 //go:noinline
    634 func two8ur(x uint8) uint8 {
    635 	return x >> 1 >> 1
    636 }
    637 
    638 func TestShiftCombine(t *testing.T) {
    639 	if got, want := two64l(4), int64(16); want != got {
    640 		t.Errorf("4<<1<<1 == %d, want %d", got, want)
    641 	}
    642 	if got, want := two64r(64), int64(16); want != got {
    643 		t.Errorf("64>>1>>1 == %d, want %d", got, want)
    644 	}
    645 	if got, want := two64ur(64), uint64(16); want != got {
    646 		t.Errorf("64>>1>>1 == %d, want %d", got, want)
    647 	}
    648 	if got, want := two32l(4), int32(16); want != got {
    649 		t.Errorf("4<<1<<1 == %d, want %d", got, want)
    650 	}
    651 	if got, want := two32r(64), int32(16); want != got {
    652 		t.Errorf("64>>1>>1 == %d, want %d", got, want)
    653 	}
    654 	if got, want := two32ur(64), uint32(16); want != got {
    655 		t.Errorf("64>>1>>1 == %d, want %d", got, want)
    656 	}
    657 	if got, want := two16l(4), int16(16); want != got {
    658 		t.Errorf("4<<1<<1 == %d, want %d", got, want)
    659 	}
    660 	if got, want := two16r(64), int16(16); want != got {
    661 		t.Errorf("64>>1>>1 == %d, want %d", got, want)
    662 	}
    663 	if got, want := two16ur(64), uint16(16); want != got {
    664 		t.Errorf("64>>1>>1 == %d, want %d", got, want)
    665 	}
    666 	if got, want := two8l(4), int8(16); want != got {
    667 		t.Errorf("4<<1<<1 == %d, want %d", got, want)
    668 	}
    669 	if got, want := two8r(64), int8(16); want != got {
    670 		t.Errorf("64>>1>>1 == %d, want %d", got, want)
    671 	}
    672 	if got, want := two8ur(64), uint8(16); want != got {
    673 		t.Errorf("64>>1>>1 == %d, want %d", got, want)
    674 	}
    675 
    676 }
    677 
    678 //go:noinline
    679 func three64l(x int64) int64 {
    680 	return x << 3 >> 1 << 2
    681 }
    682 
    683 //go:noinline
    684 func three64ul(x uint64) uint64 {
    685 	return x << 3 >> 1 << 2
    686 }
    687 
    688 //go:noinline
    689 func three64r(x int64) int64 {
    690 	return x >> 3 << 1 >> 2
    691 }
    692 
    693 //go:noinline
    694 func three64ur(x uint64) uint64 {
    695 	return x >> 3 << 1 >> 2
    696 }
    697 
    698 //go:noinline
    699 func three32l(x int32) int32 {
    700 	return x << 3 >> 1 << 2
    701 }
    702 
    703 //go:noinline
    704 func three32ul(x uint32) uint32 {
    705 	return x << 3 >> 1 << 2
    706 }
    707 
    708 //go:noinline
    709 func three32r(x int32) int32 {
    710 	return x >> 3 << 1 >> 2
    711 }
    712 
    713 //go:noinline
    714 func three32ur(x uint32) uint32 {
    715 	return x >> 3 << 1 >> 2
    716 }
    717 
    718 //go:noinline
    719 func three16l(x int16) int16 {
    720 	return x << 3 >> 1 << 2
    721 }
    722 
    723 //go:noinline
    724 func three16ul(x uint16) uint16 {
    725 	return x << 3 >> 1 << 2
    726 }
    727 
    728 //go:noinline
    729 func three16r(x int16) int16 {
    730 	return x >> 3 << 1 >> 2
    731 }
    732 
    733 //go:noinline
    734 func three16ur(x uint16) uint16 {
    735 	return x >> 3 << 1 >> 2
    736 }
    737 
    738 //go:noinline
    739 func three8l(x int8) int8 {
    740 	return x << 3 >> 1 << 2
    741 }
    742 
    743 //go:noinline
    744 func three8ul(x uint8) uint8 {
    745 	return x << 3 >> 1 << 2
    746 }
    747 
    748 //go:noinline
    749 func three8r(x int8) int8 {
    750 	return x >> 3 << 1 >> 2
    751 }
    752 
    753 //go:noinline
    754 func three8ur(x uint8) uint8 {
    755 	return x >> 3 << 1 >> 2
    756 }
    757 
    758 func TestShiftCombine3(t *testing.T) {
    759 	if got, want := three64l(4), int64(64); want != got {
    760 		t.Errorf("4<<1<<1 == %d, want %d", got, want)
    761 	}
    762 	if got, want := three64ul(4), uint64(64); want != got {
    763 		t.Errorf("4<<1<<1 == %d, want %d", got, want)
    764 	}
    765 	if got, want := three64r(64), int64(4); want != got {
    766 		t.Errorf("64>>1>>1 == %d, want %d", got, want)
    767 	}
    768 	if got, want := three64ur(64), uint64(4); want != got {
    769 		t.Errorf("64>>1>>1 == %d, want %d", got, want)
    770 	}
    771 	if got, want := three32l(4), int32(64); want != got {
    772 		t.Errorf("4<<1<<1 == %d, want %d", got, want)
    773 	}
    774 	if got, want := three32ul(4), uint32(64); want != got {
    775 		t.Errorf("4<<1<<1 == %d, want %d", got, want)
    776 	}
    777 	if got, want := three32r(64), int32(4); want != got {
    778 		t.Errorf("64>>1>>1 == %d, want %d", got, want)
    779 	}
    780 	if got, want := three32ur(64), uint32(4); want != got {
    781 		t.Errorf("64>>1>>1 == %d, want %d", got, want)
    782 	}
    783 	if got, want := three16l(4), int16(64); want != got {
    784 		t.Errorf("4<<1<<1 == %d, want %d", got, want)
    785 	}
    786 	if got, want := three16ul(4), uint16(64); want != got {
    787 		t.Errorf("4<<1<<1 == %d, want %d", got, want)
    788 	}
    789 	if got, want := three16r(64), int16(4); want != got {
    790 		t.Errorf("64>>1>>1 == %d, want %d", got, want)
    791 	}
    792 	if got, want := three16ur(64), uint16(4); want != got {
    793 		t.Errorf("64>>1>>1 == %d, want %d", got, want)
    794 	}
    795 	if got, want := three8l(4), int8(64); want != got {
    796 		t.Errorf("4<<1<<1 == %d, want %d", got, want)
    797 	}
    798 	if got, want := three8ul(4), uint8(64); want != got {
    799 		t.Errorf("4<<1<<1 == %d, want %d", got, want)
    800 	}
    801 	if got, want := three8r(64), int8(4); want != got {
    802 		t.Errorf("64>>1>>1 == %d, want %d", got, want)
    803 	}
    804 	if got, want := three8ur(64), uint8(4); want != got {
    805 		t.Errorf("64>>1>>1 == %d, want %d", got, want)
    806 	}
    807 }
    808 
    809 var (
    810 	one64  int64  = 1
    811 	one64u uint64 = 1
    812 	one32  int32  = 1
    813 	one32u uint32 = 1
    814 	one16  int16  = 1
    815 	one16u uint16 = 1
    816 	one8   int8   = 1
    817 	one8u  uint8  = 1
    818 )
    819 
    820 func TestShiftLargeCombine(t *testing.T) {
    821 	var N uint64 = 0x8000000000000000
    822 	if one64<<N<<N == 1 {
    823 		t.Errorf("shift overflow mishandled")
    824 	}
    825 	if one64>>N>>N == 1 {
    826 		t.Errorf("shift overflow mishandled")
    827 	}
    828 	if one64u>>N>>N == 1 {
    829 		t.Errorf("shift overflow mishandled")
    830 	}
    831 	if one32<<N<<N == 1 {
    832 		t.Errorf("shift overflow mishandled")
    833 	}
    834 	if one32>>N>>N == 1 {
    835 		t.Errorf("shift overflow mishandled")
    836 	}
    837 	if one32u>>N>>N == 1 {
    838 		t.Errorf("shift overflow mishandled")
    839 	}
    840 	if one16<<N<<N == 1 {
    841 		t.Errorf("shift overflow mishandled")
    842 	}
    843 	if one16>>N>>N == 1 {
    844 		t.Errorf("shift overflow mishandled")
    845 	}
    846 	if one16u>>N>>N == 1 {
    847 		t.Errorf("shift overflow mishandled")
    848 	}
    849 	if one8<<N<<N == 1 {
    850 		t.Errorf("shift overflow mishandled")
    851 	}
    852 	if one8>>N>>N == 1 {
    853 		t.Errorf("shift overflow mishandled")
    854 	}
    855 	if one8u>>N>>N == 1 {
    856 		t.Errorf("shift overflow mishandled")
    857 	}
    858 }
    859 
    860 func TestShiftLargeCombine3(t *testing.T) {
    861 	var N uint64 = 0x8000000000000001
    862 	if one64<<N>>2<<N == 1 {
    863 		t.Errorf("shift overflow mishandled")
    864 	}
    865 	if one64u<<N>>2<<N == 1 {
    866 		t.Errorf("shift overflow mishandled")
    867 	}
    868 	if one64>>N<<2>>N == 1 {
    869 		t.Errorf("shift overflow mishandled")
    870 	}
    871 	if one64u>>N<<2>>N == 1 {
    872 		t.Errorf("shift overflow mishandled")
    873 	}
    874 	if one32<<N>>2<<N == 1 {
    875 		t.Errorf("shift overflow mishandled")
    876 	}
    877 	if one32u<<N>>2<<N == 1 {
    878 		t.Errorf("shift overflow mishandled")
    879 	}
    880 	if one32>>N<<2>>N == 1 {
    881 		t.Errorf("shift overflow mishandled")
    882 	}
    883 	if one32u>>N<<2>>N == 1 {
    884 		t.Errorf("shift overflow mishandled")
    885 	}
    886 	if one16<<N>>2<<N == 1 {
    887 		t.Errorf("shift overflow mishandled")
    888 	}
    889 	if one16u<<N>>2<<N == 1 {
    890 		t.Errorf("shift overflow mishandled")
    891 	}
    892 	if one16>>N<<2>>N == 1 {
    893 		t.Errorf("shift overflow mishandled")
    894 	}
    895 	if one16u>>N<<2>>N == 1 {
    896 		t.Errorf("shift overflow mishandled")
    897 	}
    898 	if one8<<N>>2<<N == 1 {
    899 		t.Errorf("shift overflow mishandled")
    900 	}
    901 	if one8u<<N>>2<<N == 1 {
    902 		t.Errorf("shift overflow mishandled")
    903 	}
    904 	if one8>>N<<2>>N == 1 {
    905 		t.Errorf("shift overflow mishandled")
    906 	}
    907 	if one8u>>N<<2>>N == 1 {
    908 		t.Errorf("shift overflow mishandled")
    909 	}
    910 }
    911 
    912 func TestShiftGeneric(t *testing.T) {
    913 	for _, test := range [...]struct {
    914 		valueWidth int
    915 		signed     bool
    916 		shiftWidth int
    917 		left       bool
    918 		f          interface{}
    919 	}{
    920 		{64, true, 64, true, func(n int64, s uint64) int64 { return n << s }},
    921 		{64, true, 64, false, func(n int64, s uint64) int64 { return n >> s }},
    922 		{64, false, 64, false, func(n uint64, s uint64) uint64 { return n >> s }},
    923 		{64, true, 32, true, func(n int64, s uint32) int64 { return n << s }},
    924 		{64, true, 32, false, func(n int64, s uint32) int64 { return n >> s }},
    925 		{64, false, 32, false, func(n uint64, s uint32) uint64 { return n >> s }},
    926 		{64, true, 16, true, func(n int64, s uint16) int64 { return n << s }},
    927 		{64, true, 16, false, func(n int64, s uint16) int64 { return n >> s }},
    928 		{64, false, 16, false, func(n uint64, s uint16) uint64 { return n >> s }},
    929 		{64, true, 8, true, func(n int64, s uint8) int64 { return n << s }},
    930 		{64, true, 8, false, func(n int64, s uint8) int64 { return n >> s }},
    931 		{64, false, 8, false, func(n uint64, s uint8) uint64 { return n >> s }},
    932 
    933 		{32, true, 64, true, func(n int32, s uint64) int32 { return n << s }},
    934 		{32, true, 64, false, func(n int32, s uint64) int32 { return n >> s }},
    935 		{32, false, 64, false, func(n uint32, s uint64) uint32 { return n >> s }},
    936 		{32, true, 32, true, func(n int32, s uint32) int32 { return n << s }},
    937 		{32, true, 32, false, func(n int32, s uint32) int32 { return n >> s }},
    938 		{32, false, 32, false, func(n uint32, s uint32) uint32 { return n >> s }},
    939 		{32, true, 16, true, func(n int32, s uint16) int32 { return n << s }},
    940 		{32, true, 16, false, func(n int32, s uint16) int32 { return n >> s }},
    941 		{32, false, 16, false, func(n uint32, s uint16) uint32 { return n >> s }},
    942 		{32, true, 8, true, func(n int32, s uint8) int32 { return n << s }},
    943 		{32, true, 8, false, func(n int32, s uint8) int32 { return n >> s }},
    944 		{32, false, 8, false, func(n uint32, s uint8) uint32 { return n >> s }},
    945 
    946 		{16, true, 64, true, func(n int16, s uint64) int16 { return n << s }},
    947 		{16, true, 64, false, func(n int16, s uint64) int16 { return n >> s }},
    948 		{16, false, 64, false, func(n uint16, s uint64) uint16 { return n >> s }},
    949 		{16, true, 32, true, func(n int16, s uint32) int16 { return n << s }},
    950 		{16, true, 32, false, func(n int16, s uint32) int16 { return n >> s }},
    951 		{16, false, 32, false, func(n uint16, s uint32) uint16 { return n >> s }},
    952 		{16, true, 16, true, func(n int16, s uint16) int16 { return n << s }},
    953 		{16, true, 16, false, func(n int16, s uint16) int16 { return n >> s }},
    954 		{16, false, 16, false, func(n uint16, s uint16) uint16 { return n >> s }},
    955 		{16, true, 8, true, func(n int16, s uint8) int16 { return n << s }},
    956 		{16, true, 8, false, func(n int16, s uint8) int16 { return n >> s }},
    957 		{16, false, 8, false, func(n uint16, s uint8) uint16 { return n >> s }},
    958 
    959 		{8, true, 64, true, func(n int8, s uint64) int8 { return n << s }},
    960 		{8, true, 64, false, func(n int8, s uint64) int8 { return n >> s }},
    961 		{8, false, 64, false, func(n uint8, s uint64) uint8 { return n >> s }},
    962 		{8, true, 32, true, func(n int8, s uint32) int8 { return n << s }},
    963 		{8, true, 32, false, func(n int8, s uint32) int8 { return n >> s }},
    964 		{8, false, 32, false, func(n uint8, s uint32) uint8 { return n >> s }},
    965 		{8, true, 16, true, func(n int8, s uint16) int8 { return n << s }},
    966 		{8, true, 16, false, func(n int8, s uint16) int8 { return n >> s }},
    967 		{8, false, 16, false, func(n uint8, s uint16) uint8 { return n >> s }},
    968 		{8, true, 8, true, func(n int8, s uint8) int8 { return n << s }},
    969 		{8, true, 8, false, func(n int8, s uint8) int8 { return n >> s }},
    970 		{8, false, 8, false, func(n uint8, s uint8) uint8 { return n >> s }},
    971 	} {
    972 		fv := reflect.ValueOf(test.f)
    973 		var args [2]reflect.Value
    974 		for i := 0; i < test.valueWidth; i++ {
    975 			// Build value to be shifted.
    976 			var n int64 = 1
    977 			for j := 0; j < i; j++ {
    978 				n <<= 1
    979 			}
    980 			args[0] = reflect.ValueOf(n).Convert(fv.Type().In(0))
    981 			for s := 0; s <= test.shiftWidth; s++ {
    982 				args[1] = reflect.ValueOf(s).Convert(fv.Type().In(1))
    983 
    984 				// Compute desired result. We're testing variable shifts
    985 				// assuming constant shifts are correct.
    986 				r := n
    987 				var op string
    988 				switch {
    989 				case test.left:
    990 					op = "<<"
    991 					for j := 0; j < s; j++ {
    992 						r <<= 1
    993 					}
    994 					switch test.valueWidth {
    995 					case 32:
    996 						r = int64(int32(r))
    997 					case 16:
    998 						r = int64(int16(r))
    999 					case 8:
   1000 						r = int64(int8(r))
   1001 					}
   1002 				case test.signed:
   1003 					op = ">>"
   1004 					switch test.valueWidth {
   1005 					case 32:
   1006 						r = int64(int32(r))
   1007 					case 16:
   1008 						r = int64(int16(r))
   1009 					case 8:
   1010 						r = int64(int8(r))
   1011 					}
   1012 					for j := 0; j < s; j++ {
   1013 						r >>= 1
   1014 					}
   1015 				default:
   1016 					op = ">>>"
   1017 					for j := 0; j < s; j++ {
   1018 						r = int64(uint64(r) >> 1)
   1019 					}
   1020 				}
   1021 
   1022 				// Call function.
   1023 				res := fv.Call(args[:])[0].Convert(reflect.ValueOf(r).Type())
   1024 
   1025 				if res.Int() != r {
   1026 					t.Errorf("%s%dx%d(%x,%x)=%x, want %x", op, test.valueWidth, test.shiftWidth, n, s, res.Int(), r)
   1027 				}
   1028 			}
   1029 		}
   1030 	}
   1031 }
   1032