github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/cmd/compile/internal/gc/testdata/arith_test.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Tests arithmetic expressions 6 7 package main 8 9 import ( 10 "runtime" 11 "testing" 12 ) 13 14 const ( 15 y = 0x0fffFFFF 16 ) 17 18 var ( 19 g8 int8 20 g16 int16 21 g32 int32 22 g64 int64 23 ) 24 25 //go:noinline 26 func lshNop1(x uint64) uint64 { 27 // two outer shifts should be removed 28 return (((x << 5) >> 2) << 2) 29 } 30 31 //go:noinline 32 func lshNop2(x uint64) uint64 { 33 return (((x << 5) >> 2) << 3) 34 } 35 36 //go:noinline 37 func lshNop3(x uint64) uint64 { 38 return (((x << 5) >> 2) << 6) 39 } 40 41 //go:noinline 42 func lshNotNop(x uint64) uint64 { 43 // outer shift can't be removed 44 return (((x << 5) >> 2) << 1) 45 } 46 47 //go:noinline 48 func rshNop1(x uint64) uint64 { 49 return (((x >> 5) << 2) >> 2) 50 } 51 52 //go:noinline 53 func rshNop2(x uint64) uint64 { 54 return (((x >> 5) << 2) >> 3) 55 } 56 57 //go:noinline 58 func rshNop3(x uint64) uint64 { 59 return (((x >> 5) << 2) >> 6) 60 } 61 62 //go:noinline 63 func rshNotNop(x uint64) uint64 { 64 return (((x >> 5) << 2) >> 1) 65 } 66 67 func testShiftRemoval(t *testing.T) { 68 allSet := ^uint64(0) 69 if want, got := uint64(0x7ffffffffffffff), rshNop1(allSet); want != got { 70 t.Errorf("testShiftRemoval rshNop1 failed, wanted %d got %d", want, got) 71 } 72 if want, got := uint64(0x3ffffffffffffff), rshNop2(allSet); want != got { 73 t.Errorf("testShiftRemoval rshNop2 failed, wanted %d got %d", want, got) 74 } 75 if want, got := uint64(0x7fffffffffffff), rshNop3(allSet); want != got { 76 t.Errorf("testShiftRemoval rshNop3 failed, wanted %d got %d", want, got) 77 } 78 if want, got := uint64(0xffffffffffffffe), rshNotNop(allSet); want != got { 79 t.Errorf("testShiftRemoval rshNotNop failed, wanted %d got %d", want, got) 80 } 81 if want, got := uint64(0xffffffffffffffe0), lshNop1(allSet); want != got { 82 t.Errorf("testShiftRemoval lshNop1 failed, wanted %d got %d", want, got) 83 } 84 if want, got := uint64(0xffffffffffffffc0), lshNop2(allSet); want != got { 85 t.Errorf("testShiftRemoval lshNop2 failed, wanted %d got %d", want, got) 86 } 87 if want, got := uint64(0xfffffffffffffe00), lshNop3(allSet); want != got { 88 t.Errorf("testShiftRemoval lshNop3 failed, wanted %d got %d", want, got) 89 } 90 if want, got := uint64(0x7ffffffffffffff0), lshNotNop(allSet); want != got { 91 t.Errorf("testShiftRemoval lshNotNop failed, wanted %d got %d", want, got) 92 } 93 } 94 95 //go:noinline 96 func parseLE64(b []byte) uint64 { 97 // skip the first two bytes, and parse the remaining 8 as a uint64 98 return uint64(b[2]) | uint64(b[3])<<8 | uint64(b[4])<<16 | uint64(b[5])<<24 | 99 uint64(b[6])<<32 | uint64(b[7])<<40 | uint64(b[8])<<48 | uint64(b[9])<<56 100 } 101 102 //go:noinline 103 func parseLE32(b []byte) uint32 { 104 return uint32(b[2]) | uint32(b[3])<<8 | uint32(b[4])<<16 | uint32(b[5])<<24 105 } 106 107 //go:noinline 108 func parseLE16(b []byte) uint16 { 109 return uint16(b[2]) | uint16(b[3])<<8 110 } 111 112 // testLoadCombine tests for issue #14694 where load combining didn't respect the pointer offset. 113 func testLoadCombine(t *testing.T) { 114 testData := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09} 115 if want, got := uint64(0x0908070605040302), parseLE64(testData); want != got { 116 t.Errorf("testLoadCombine failed, wanted %d got %d", want, got) 117 } 118 if want, got := uint32(0x05040302), parseLE32(testData); want != got { 119 t.Errorf("testLoadCombine failed, wanted %d got %d", want, got) 120 } 121 if want, got := uint16(0x0302), parseLE16(testData); want != got { 122 t.Errorf("testLoadCombine failed, wanted %d got %d", want, got) 123 } 124 } 125 126 var loadSymData = [...]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08} 127 128 func testLoadSymCombine(t *testing.T) { 129 w2 := uint16(0x0201) 130 g2 := uint16(loadSymData[0]) | uint16(loadSymData[1])<<8 131 if g2 != w2 { 132 t.Errorf("testLoadSymCombine failed, wanted %d got %d", w2, g2) 133 } 134 w4 := uint32(0x04030201) 135 g4 := uint32(loadSymData[0]) | uint32(loadSymData[1])<<8 | 136 uint32(loadSymData[2])<<16 | uint32(loadSymData[3])<<24 137 if g4 != w4 { 138 t.Errorf("testLoadSymCombine failed, wanted %d got %d", w4, g4) 139 } 140 w8 := uint64(0x0807060504030201) 141 g8 := uint64(loadSymData[0]) | uint64(loadSymData[1])<<8 | 142 uint64(loadSymData[2])<<16 | uint64(loadSymData[3])<<24 | 143 uint64(loadSymData[4])<<32 | uint64(loadSymData[5])<<40 | 144 uint64(loadSymData[6])<<48 | uint64(loadSymData[7])<<56 145 if g8 != w8 { 146 t.Errorf("testLoadSymCombine failed, wanted %d got %d", w8, g8) 147 } 148 } 149 150 //go:noinline 151 func invalidAdd_ssa(x uint32) uint32 { 152 return x + y + y + y + y + y + y + y + y + y + y + y + y + y + y + y + y + y 153 } 154 155 //go:noinline 156 func invalidSub_ssa(x uint32) uint32 { 157 return x - y - y - y - y - y - y - y - y - y - y - y - y - y - y - y - y - y 158 } 159 160 //go:noinline 161 func invalidMul_ssa(x uint32) uint32 { 162 return x * y * y * y * y * y * y * y * y * y * y * y * y * y * y * y * y * y 163 } 164 165 // testLargeConst tests a situation where larger than 32 bit consts were passed to ADDL 166 // causing an invalid instruction error. 167 func testLargeConst(t *testing.T) { 168 if want, got := uint32(268435440), invalidAdd_ssa(1); want != got { 169 t.Errorf("testLargeConst add failed, wanted %d got %d", want, got) 170 } 171 if want, got := uint32(4026531858), invalidSub_ssa(1); want != got { 172 t.Errorf("testLargeConst sub failed, wanted %d got %d", want, got) 173 } 174 if want, got := uint32(268435455), invalidMul_ssa(1); want != got { 175 t.Errorf("testLargeConst mul failed, wanted %d got %d", want, got) 176 } 177 } 178 179 // testArithRshConst ensures that "const >> const" right shifts correctly perform 180 // sign extension on the lhs constant 181 func testArithRshConst(t *testing.T) { 182 wantu := uint64(0x4000000000000000) 183 if got := arithRshuConst_ssa(); got != wantu { 184 t.Errorf("arithRshuConst failed, wanted %d got %d", wantu, got) 185 } 186 187 wants := int64(-0x4000000000000000) 188 if got := arithRshConst_ssa(); got != wants { 189 t.Errorf("arithRshConst failed, wanted %d got %d", wants, got) 190 } 191 } 192 193 //go:noinline 194 func arithRshuConst_ssa() uint64 { 195 y := uint64(0x8000000000000001) 196 z := uint64(1) 197 return uint64(y >> z) 198 } 199 200 //go:noinline 201 func arithRshConst_ssa() int64 { 202 y := int64(-0x8000000000000000) 203 z := uint64(1) 204 return int64(y >> z) 205 } 206 207 //go:noinline 208 func arithConstShift_ssa(x int64) int64 { 209 return x >> 100 210 } 211 212 // testArithConstShift tests that right shift by large constants preserve 213 // the sign of the input. 214 func testArithConstShift(t *testing.T) { 215 want := int64(-1) 216 if got := arithConstShift_ssa(-1); want != got { 217 t.Errorf("arithConstShift_ssa(-1) failed, wanted %d got %d", want, got) 218 } 219 want = 0 220 if got := arithConstShift_ssa(1); want != got { 221 t.Errorf("arithConstShift_ssa(1) failed, wanted %d got %d", want, got) 222 } 223 } 224 225 // overflowConstShift_ssa verifes that constant folding for shift 226 // doesn't wrap (i.e. x << MAX_INT << 1 doesn't get folded to x << 0). 227 //go:noinline 228 func overflowConstShift64_ssa(x int64) int64 { 229 return x << uint64(0xffffffffffffffff) << uint64(1) 230 } 231 232 //go:noinline 233 func overflowConstShift32_ssa(x int64) int32 { 234 return int32(x) << uint32(0xffffffff) << uint32(1) 235 } 236 237 //go:noinline 238 func overflowConstShift16_ssa(x int64) int16 { 239 return int16(x) << uint16(0xffff) << uint16(1) 240 } 241 242 //go:noinline 243 func overflowConstShift8_ssa(x int64) int8 { 244 return int8(x) << uint8(0xff) << uint8(1) 245 } 246 247 func testOverflowConstShift(t *testing.T) { 248 want := int64(0) 249 for x := int64(-127); x < int64(127); x++ { 250 got := overflowConstShift64_ssa(x) 251 if want != got { 252 t.Errorf("overflowShift64 failed, wanted %d got %d", want, got) 253 } 254 got = int64(overflowConstShift32_ssa(x)) 255 if want != got { 256 t.Errorf("overflowShift32 failed, wanted %d got %d", want, got) 257 } 258 got = int64(overflowConstShift16_ssa(x)) 259 if want != got { 260 t.Errorf("overflowShift16 failed, wanted %d got %d", want, got) 261 } 262 got = int64(overflowConstShift8_ssa(x)) 263 if want != got { 264 t.Errorf("overflowShift8 failed, wanted %d got %d", want, got) 265 } 266 } 267 } 268 269 // test64BitConstMult tests that rewrite rules don't fold 64 bit constants 270 // into multiply instructions. 271 func test64BitConstMult(t *testing.T) { 272 want := int64(103079215109) 273 if got := test64BitConstMult_ssa(1, 2); want != got { 274 t.Errorf("test64BitConstMult failed, wanted %d got %d", want, got) 275 } 276 } 277 278 //go:noinline 279 func test64BitConstMult_ssa(a, b int64) int64 { 280 return 34359738369*a + b*34359738370 281 } 282 283 // test64BitConstAdd tests that rewrite rules don't fold 64 bit constants 284 // into add instructions. 285 func test64BitConstAdd(t *testing.T) { 286 want := int64(3567671782835376650) 287 if got := test64BitConstAdd_ssa(1, 2); want != got { 288 t.Errorf("test64BitConstAdd failed, wanted %d got %d", want, got) 289 } 290 } 291 292 //go:noinline 293 func test64BitConstAdd_ssa(a, b int64) int64 { 294 return a + 575815584948629622 + b + 2991856197886747025 295 } 296 297 // testRegallocCVSpill tests that regalloc spills a value whose last use is the 298 // current value. 299 func testRegallocCVSpill(t *testing.T) { 300 want := int8(-9) 301 if got := testRegallocCVSpill_ssa(1, 2, 3, 4); want != got { 302 t.Errorf("testRegallocCVSpill failed, wanted %d got %d", want, got) 303 } 304 } 305 306 //go:noinline 307 func testRegallocCVSpill_ssa(a, b, c, d int8) int8 { 308 return a + -32 + b + 63*c*-87*d 309 } 310 311 func testBitwiseLogic(t *testing.T) { 312 a, b := uint32(57623283), uint32(1314713839) 313 if want, got := uint32(38551779), testBitwiseAnd_ssa(a, b); want != got { 314 t.Errorf("testBitwiseAnd failed, wanted %d got %d", want, got) 315 } 316 if want, got := uint32(1333785343), testBitwiseOr_ssa(a, b); want != got { 317 t.Errorf("testBitwiseOr failed, wanted %d got %d", want, got) 318 } 319 if want, got := uint32(1295233564), testBitwiseXor_ssa(a, b); want != got { 320 t.Errorf("testBitwiseXor failed, wanted %d got %d", want, got) 321 } 322 if want, got := int32(832), testBitwiseLsh_ssa(13, 4, 2); want != got { 323 t.Errorf("testBitwiseLsh failed, wanted %d got %d", want, got) 324 } 325 if want, got := int32(0), testBitwiseLsh_ssa(13, 25, 15); want != got { 326 t.Errorf("testBitwiseLsh failed, wanted %d got %d", want, got) 327 } 328 if want, got := int32(0), testBitwiseLsh_ssa(-13, 25, 15); want != got { 329 t.Errorf("testBitwiseLsh failed, wanted %d got %d", want, got) 330 } 331 if want, got := int32(-13), testBitwiseRsh_ssa(-832, 4, 2); want != got { 332 t.Errorf("testBitwiseRsh failed, wanted %d got %d", want, got) 333 } 334 if want, got := int32(0), testBitwiseRsh_ssa(13, 25, 15); want != got { 335 t.Errorf("testBitwiseRsh failed, wanted %d got %d", want, got) 336 } 337 if want, got := int32(-1), testBitwiseRsh_ssa(-13, 25, 15); want != got { 338 t.Errorf("testBitwiseRsh failed, wanted %d got %d", want, got) 339 } 340 if want, got := uint32(0x3ffffff), testBitwiseRshU_ssa(0xffffffff, 4, 2); want != got { 341 t.Errorf("testBitwiseRshU failed, wanted %d got %d", want, got) 342 } 343 if want, got := uint32(0), testBitwiseRshU_ssa(13, 25, 15); want != got { 344 t.Errorf("testBitwiseRshU failed, wanted %d got %d", want, got) 345 } 346 if want, got := uint32(0), testBitwiseRshU_ssa(0x8aaaaaaa, 25, 15); want != got { 347 t.Errorf("testBitwiseRshU failed, wanted %d got %d", want, got) 348 } 349 } 350 351 //go:noinline 352 func testBitwiseAnd_ssa(a, b uint32) uint32 { 353 return a & b 354 } 355 356 //go:noinline 357 func testBitwiseOr_ssa(a, b uint32) uint32 { 358 return a | b 359 } 360 361 //go:noinline 362 func testBitwiseXor_ssa(a, b uint32) uint32 { 363 return a ^ b 364 } 365 366 //go:noinline 367 func testBitwiseLsh_ssa(a int32, b, c uint32) int32 { 368 return a << b << c 369 } 370 371 //go:noinline 372 func testBitwiseRsh_ssa(a int32, b, c uint32) int32 { 373 return a >> b >> c 374 } 375 376 //go:noinline 377 func testBitwiseRshU_ssa(a uint32, b, c uint32) uint32 { 378 return a >> b >> c 379 } 380 381 //go:noinline 382 func testShiftCX_ssa() int { 383 v1 := uint8(3) 384 v4 := (v1 * v1) ^ v1 | v1 - v1 - v1&v1 ^ uint8(3+2) + v1*1>>0 - v1 | 1 | v1<<(2*3|0-0*0^1) 385 v5 := v4>>(3-0-uint(3)) | v1 | v1 + v1 ^ v4<<(0+1|3&1)<<(uint64(1)<<0*2*0<<0) ^ v1 386 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 387 v7 := v6 & v5 << 0 388 v1++ 389 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 390 v7-- 391 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)) 392 } 393 394 func testShiftCX(t *testing.T) { 395 want := 141 396 if got := testShiftCX_ssa(); want != got { 397 t.Errorf("testShiftCX failed, wanted %d got %d", want, got) 398 } 399 } 400 401 // testSubqToNegq ensures that the SUBQ -> NEGQ translation works correctly. 402 func testSubqToNegq(t *testing.T) { 403 want := int64(-318294940372190156) 404 if got := testSubqToNegq_ssa(1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2); want != got { 405 t.Errorf("testSubqToNegq failed, wanted %d got %d", want, got) 406 } 407 } 408 409 //go:noinline 410 func testSubqToNegq_ssa(a, b, c, d, e, f, g, h, i, j, k int64) int64 { 411 return a + 8207351403619448057 - b - 1779494519303207690 + c*8810076340510052032*d - 4465874067674546219 - e*4361839741470334295 - f + 8688847565426072650*g*8065564729145417479 412 } 413 414 func testOcom(t *testing.T) { 415 want1, want2 := int32(0x55555555), int32(-0x55555556) 416 if got1, got2 := testOcom_ssa(0x55555555, 0x55555555); want1 != got1 || want2 != got2 { 417 t.Errorf("testOcom failed, wanted %d and %d got %d and %d", want1, want2, got1, got2) 418 } 419 } 420 421 //go:noinline 422 func testOcom_ssa(a, b int32) (int32, int32) { 423 return ^^^^a, ^^^^^b 424 } 425 426 func lrot1_ssa(w uint8, x uint16, y uint32, z uint64) (a uint8, b uint16, c uint32, d uint64) { 427 a = (w << 5) | (w >> 3) 428 b = (x << 13) | (x >> 3) 429 c = (y << 29) | (y >> 3) 430 d = (z << 61) | (z >> 3) 431 return 432 } 433 434 //go:noinline 435 func lrot2_ssa(w, n uint32) uint32 { 436 // Want to be sure that a "rotate by 32" which 437 // is really 0 | (w >> 0) == w 438 // is correctly compiled. 439 return (w << n) | (w >> (32 - n)) 440 } 441 442 //go:noinline 443 func lrot3_ssa(w uint32) uint32 { 444 // Want to be sure that a "rotate by 32" which 445 // is really 0 | (w >> 0) == w 446 // is correctly compiled. 447 return (w << 32) | (w >> (32 - 32)) 448 } 449 450 func testLrot(t *testing.T) { 451 wantA, wantB, wantC, wantD := uint8(0xe1), uint16(0xe001), 452 uint32(0xe0000001), uint64(0xe000000000000001) 453 a, b, c, d := lrot1_ssa(0xf, 0xf, 0xf, 0xf) 454 if a != wantA || b != wantB || c != wantC || d != wantD { 455 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) 456 } 457 x := lrot2_ssa(0xb0000001, 32) 458 wantX := uint32(0xb0000001) 459 if x != wantX { 460 t.Errorf("lrot2_ssa(0xb0000001, 32)=%d, got %d", wantX, x) 461 } 462 x = lrot3_ssa(0xb0000001) 463 if x != wantX { 464 t.Errorf("lrot3_ssa(0xb0000001)=%d, got %d", wantX, x) 465 } 466 467 } 468 469 //go:noinline 470 func sub1_ssa() uint64 { 471 v1 := uint64(3) // uint64 472 return v1*v1 - (v1&v1)&v1 473 } 474 475 //go:noinline 476 func sub2_ssa() uint8 { 477 v1 := uint8(0) 478 v3 := v1 + v1 + v1 ^ v1 | 3 + v1 ^ v1 | v1 ^ v1 479 v1-- // dev.ssa doesn't see this one 480 return v1 ^ v1*v1 - v3 481 } 482 483 func testSubConst(t *testing.T) { 484 x1 := sub1_ssa() 485 want1 := uint64(6) 486 if x1 != want1 { 487 t.Errorf("sub1_ssa()=%d, got %d", want1, x1) 488 } 489 x2 := sub2_ssa() 490 want2 := uint8(251) 491 if x2 != want2 { 492 t.Errorf("sub2_ssa()=%d, got %d", want2, x2) 493 } 494 } 495 496 //go:noinline 497 func orPhi_ssa(a bool, x int) int { 498 v := 0 499 if a { 500 v = -1 501 } else { 502 v = -1 503 } 504 return x | v 505 } 506 507 func testOrPhi(t *testing.T) { 508 if want, got := -1, orPhi_ssa(true, 4); got != want { 509 t.Errorf("orPhi_ssa(true, 4)=%d, want %d", got, want) 510 } 511 if want, got := -1, orPhi_ssa(false, 0); got != want { 512 t.Errorf("orPhi_ssa(false, 0)=%d, want %d", got, want) 513 } 514 } 515 516 //go:noinline 517 func addshiftLL_ssa(a, b uint32) uint32 { 518 return a + b<<3 519 } 520 521 //go:noinline 522 func subshiftLL_ssa(a, b uint32) uint32 { 523 return a - b<<3 524 } 525 526 //go:noinline 527 func rsbshiftLL_ssa(a, b uint32) uint32 { 528 return a<<3 - b 529 } 530 531 //go:noinline 532 func andshiftLL_ssa(a, b uint32) uint32 { 533 return a & (b << 3) 534 } 535 536 //go:noinline 537 func orshiftLL_ssa(a, b uint32) uint32 { 538 return a | b<<3 539 } 540 541 //go:noinline 542 func xorshiftLL_ssa(a, b uint32) uint32 { 543 return a ^ b<<3 544 } 545 546 //go:noinline 547 func bicshiftLL_ssa(a, b uint32) uint32 { 548 return a &^ (b << 3) 549 } 550 551 //go:noinline 552 func notshiftLL_ssa(a uint32) uint32 { 553 return ^(a << 3) 554 } 555 556 //go:noinline 557 func addshiftRL_ssa(a, b uint32) uint32 { 558 return a + b>>3 559 } 560 561 //go:noinline 562 func subshiftRL_ssa(a, b uint32) uint32 { 563 return a - b>>3 564 } 565 566 //go:noinline 567 func rsbshiftRL_ssa(a, b uint32) uint32 { 568 return a>>3 - b 569 } 570 571 //go:noinline 572 func andshiftRL_ssa(a, b uint32) uint32 { 573 return a & (b >> 3) 574 } 575 576 //go:noinline 577 func orshiftRL_ssa(a, b uint32) uint32 { 578 return a | b>>3 579 } 580 581 //go:noinline 582 func xorshiftRL_ssa(a, b uint32) uint32 { 583 return a ^ b>>3 584 } 585 586 //go:noinline 587 func bicshiftRL_ssa(a, b uint32) uint32 { 588 return a &^ (b >> 3) 589 } 590 591 //go:noinline 592 func notshiftRL_ssa(a uint32) uint32 { 593 return ^(a >> 3) 594 } 595 596 //go:noinline 597 func addshiftRA_ssa(a, b int32) int32 { 598 return a + b>>3 599 } 600 601 //go:noinline 602 func subshiftRA_ssa(a, b int32) int32 { 603 return a - b>>3 604 } 605 606 //go:noinline 607 func rsbshiftRA_ssa(a, b int32) int32 { 608 return a>>3 - b 609 } 610 611 //go:noinline 612 func andshiftRA_ssa(a, b int32) int32 { 613 return a & (b >> 3) 614 } 615 616 //go:noinline 617 func orshiftRA_ssa(a, b int32) int32 { 618 return a | b>>3 619 } 620 621 //go:noinline 622 func xorshiftRA_ssa(a, b int32) int32 { 623 return a ^ b>>3 624 } 625 626 //go:noinline 627 func bicshiftRA_ssa(a, b int32) int32 { 628 return a &^ (b >> 3) 629 } 630 631 //go:noinline 632 func notshiftRA_ssa(a int32) int32 { 633 return ^(a >> 3) 634 } 635 636 //go:noinline 637 func addshiftLLreg_ssa(a, b uint32, s uint8) uint32 { 638 return a + b<<s 639 } 640 641 //go:noinline 642 func subshiftLLreg_ssa(a, b uint32, s uint8) uint32 { 643 return a - b<<s 644 } 645 646 //go:noinline 647 func rsbshiftLLreg_ssa(a, b uint32, s uint8) uint32 { 648 return a<<s - b 649 } 650 651 //go:noinline 652 func andshiftLLreg_ssa(a, b uint32, s uint8) uint32 { 653 return a & (b << s) 654 } 655 656 //go:noinline 657 func orshiftLLreg_ssa(a, b uint32, s uint8) uint32 { 658 return a | b<<s 659 } 660 661 //go:noinline 662 func xorshiftLLreg_ssa(a, b uint32, s uint8) uint32 { 663 return a ^ b<<s 664 } 665 666 //go:noinline 667 func bicshiftLLreg_ssa(a, b uint32, s uint8) uint32 { 668 return a &^ (b << s) 669 } 670 671 //go:noinline 672 func notshiftLLreg_ssa(a uint32, s uint8) uint32 { 673 return ^(a << s) 674 } 675 676 //go:noinline 677 func addshiftRLreg_ssa(a, b uint32, s uint8) uint32 { 678 return a + b>>s 679 } 680 681 //go:noinline 682 func subshiftRLreg_ssa(a, b uint32, s uint8) uint32 { 683 return a - b>>s 684 } 685 686 //go:noinline 687 func rsbshiftRLreg_ssa(a, b uint32, s uint8) uint32 { 688 return a>>s - b 689 } 690 691 //go:noinline 692 func andshiftRLreg_ssa(a, b uint32, s uint8) uint32 { 693 return a & (b >> s) 694 } 695 696 //go:noinline 697 func orshiftRLreg_ssa(a, b uint32, s uint8) uint32 { 698 return a | b>>s 699 } 700 701 //go:noinline 702 func xorshiftRLreg_ssa(a, b uint32, s uint8) uint32 { 703 return a ^ b>>s 704 } 705 706 //go:noinline 707 func bicshiftRLreg_ssa(a, b uint32, s uint8) uint32 { 708 return a &^ (b >> s) 709 } 710 711 //go:noinline 712 func notshiftRLreg_ssa(a uint32, s uint8) uint32 { 713 return ^(a >> s) 714 } 715 716 //go:noinline 717 func addshiftRAreg_ssa(a, b int32, s uint8) int32 { 718 return a + b>>s 719 } 720 721 //go:noinline 722 func subshiftRAreg_ssa(a, b int32, s uint8) int32 { 723 return a - b>>s 724 } 725 726 //go:noinline 727 func rsbshiftRAreg_ssa(a, b int32, s uint8) int32 { 728 return a>>s - b 729 } 730 731 //go:noinline 732 func andshiftRAreg_ssa(a, b int32, s uint8) int32 { 733 return a & (b >> s) 734 } 735 736 //go:noinline 737 func orshiftRAreg_ssa(a, b int32, s uint8) int32 { 738 return a | b>>s 739 } 740 741 //go:noinline 742 func xorshiftRAreg_ssa(a, b int32, s uint8) int32 { 743 return a ^ b>>s 744 } 745 746 //go:noinline 747 func bicshiftRAreg_ssa(a, b int32, s uint8) int32 { 748 return a &^ (b >> s) 749 } 750 751 //go:noinline 752 func notshiftRAreg_ssa(a int32, s uint8) int32 { 753 return ^(a >> s) 754 } 755 756 // test ARM shifted ops 757 func testShiftedOps(t *testing.T) { 758 a, b := uint32(10), uint32(42) 759 if want, got := a+b<<3, addshiftLL_ssa(a, b); got != want { 760 t.Errorf("addshiftLL_ssa(10, 42) = %d want %d", got, want) 761 } 762 if want, got := a-b<<3, subshiftLL_ssa(a, b); got != want { 763 t.Errorf("subshiftLL_ssa(10, 42) = %d want %d", got, want) 764 } 765 if want, got := a<<3-b, rsbshiftLL_ssa(a, b); got != want { 766 t.Errorf("rsbshiftLL_ssa(10, 42) = %d want %d", got, want) 767 } 768 if want, got := a&(b<<3), andshiftLL_ssa(a, b); got != want { 769 t.Errorf("andshiftLL_ssa(10, 42) = %d want %d", got, want) 770 } 771 if want, got := a|b<<3, orshiftLL_ssa(a, b); got != want { 772 t.Errorf("orshiftLL_ssa(10, 42) = %d want %d", got, want) 773 } 774 if want, got := a^b<<3, xorshiftLL_ssa(a, b); got != want { 775 t.Errorf("xorshiftLL_ssa(10, 42) = %d want %d", got, want) 776 } 777 if want, got := a&^(b<<3), bicshiftLL_ssa(a, b); got != want { 778 t.Errorf("bicshiftLL_ssa(10, 42) = %d want %d", got, want) 779 } 780 if want, got := ^(a << 3), notshiftLL_ssa(a); got != want { 781 t.Errorf("notshiftLL_ssa(10) = %d want %d", got, want) 782 } 783 if want, got := a+b>>3, addshiftRL_ssa(a, b); got != want { 784 t.Errorf("addshiftRL_ssa(10, 42) = %d want %d", got, want) 785 } 786 if want, got := a-b>>3, subshiftRL_ssa(a, b); got != want { 787 t.Errorf("subshiftRL_ssa(10, 42) = %d want %d", got, want) 788 } 789 if want, got := a>>3-b, rsbshiftRL_ssa(a, b); got != want { 790 t.Errorf("rsbshiftRL_ssa(10, 42) = %d want %d", got, want) 791 } 792 if want, got := a&(b>>3), andshiftRL_ssa(a, b); got != want { 793 t.Errorf("andshiftRL_ssa(10, 42) = %d want %d", got, want) 794 } 795 if want, got := a|b>>3, orshiftRL_ssa(a, b); got != want { 796 t.Errorf("orshiftRL_ssa(10, 42) = %d want %d", got, want) 797 } 798 if want, got := a^b>>3, xorshiftRL_ssa(a, b); got != want { 799 t.Errorf("xorshiftRL_ssa(10, 42) = %d want %d", got, want) 800 } 801 if want, got := a&^(b>>3), bicshiftRL_ssa(a, b); got != want { 802 t.Errorf("bicshiftRL_ssa(10, 42) = %d want %d", got, want) 803 } 804 if want, got := ^(a >> 3), notshiftRL_ssa(a); got != want { 805 t.Errorf("notshiftRL_ssa(10) = %d want %d", got, want) 806 } 807 c, d := int32(10), int32(-42) 808 if want, got := c+d>>3, addshiftRA_ssa(c, d); got != want { 809 t.Errorf("addshiftRA_ssa(10, -42) = %d want %d", got, want) 810 } 811 if want, got := c-d>>3, subshiftRA_ssa(c, d); got != want { 812 t.Errorf("subshiftRA_ssa(10, -42) = %d want %d", got, want) 813 } 814 if want, got := c>>3-d, rsbshiftRA_ssa(c, d); got != want { 815 t.Errorf("rsbshiftRA_ssa(10, -42) = %d want %d", got, want) 816 } 817 if want, got := c&(d>>3), andshiftRA_ssa(c, d); got != want { 818 t.Errorf("andshiftRA_ssa(10, -42) = %d want %d", got, want) 819 } 820 if want, got := c|d>>3, orshiftRA_ssa(c, d); got != want { 821 t.Errorf("orshiftRA_ssa(10, -42) = %d want %d", got, want) 822 } 823 if want, got := c^d>>3, xorshiftRA_ssa(c, d); got != want { 824 t.Errorf("xorshiftRA_ssa(10, -42) = %d want %d", got, want) 825 } 826 if want, got := c&^(d>>3), bicshiftRA_ssa(c, d); got != want { 827 t.Errorf("bicshiftRA_ssa(10, -42) = %d want %d", got, want) 828 } 829 if want, got := ^(d >> 3), notshiftRA_ssa(d); got != want { 830 t.Errorf("notshiftRA_ssa(-42) = %d want %d", got, want) 831 } 832 s := uint8(3) 833 if want, got := a+b<<s, addshiftLLreg_ssa(a, b, s); got != want { 834 t.Errorf("addshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want) 835 } 836 if want, got := a-b<<s, subshiftLLreg_ssa(a, b, s); got != want { 837 t.Errorf("subshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want) 838 } 839 if want, got := a<<s-b, rsbshiftLLreg_ssa(a, b, s); got != want { 840 t.Errorf("rsbshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want) 841 } 842 if want, got := a&(b<<s), andshiftLLreg_ssa(a, b, s); got != want { 843 t.Errorf("andshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want) 844 } 845 if want, got := a|b<<s, orshiftLLreg_ssa(a, b, s); got != want { 846 t.Errorf("orshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want) 847 } 848 if want, got := a^b<<s, xorshiftLLreg_ssa(a, b, s); got != want { 849 t.Errorf("xorshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want) 850 } 851 if want, got := a&^(b<<s), bicshiftLLreg_ssa(a, b, s); got != want { 852 t.Errorf("bicshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want) 853 } 854 if want, got := ^(a << s), notshiftLLreg_ssa(a, s); got != want { 855 t.Errorf("notshiftLLreg_ssa(10) = %d want %d", got, want) 856 } 857 if want, got := a+b>>s, addshiftRLreg_ssa(a, b, s); got != want { 858 t.Errorf("addshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want) 859 } 860 if want, got := a-b>>s, subshiftRLreg_ssa(a, b, s); got != want { 861 t.Errorf("subshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want) 862 } 863 if want, got := a>>s-b, rsbshiftRLreg_ssa(a, b, s); got != want { 864 t.Errorf("rsbshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want) 865 } 866 if want, got := a&(b>>s), andshiftRLreg_ssa(a, b, s); got != want { 867 t.Errorf("andshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want) 868 } 869 if want, got := a|b>>s, orshiftRLreg_ssa(a, b, s); got != want { 870 t.Errorf("orshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want) 871 } 872 if want, got := a^b>>s, xorshiftRLreg_ssa(a, b, s); got != want { 873 t.Errorf("xorshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want) 874 } 875 if want, got := a&^(b>>s), bicshiftRLreg_ssa(a, b, s); got != want { 876 t.Errorf("bicshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want) 877 } 878 if want, got := ^(a >> s), notshiftRLreg_ssa(a, s); got != want { 879 t.Errorf("notshiftRLreg_ssa(10) = %d want %d", got, want) 880 } 881 if want, got := c+d>>s, addshiftRAreg_ssa(c, d, s); got != want { 882 t.Errorf("addshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want) 883 } 884 if want, got := c-d>>s, subshiftRAreg_ssa(c, d, s); got != want { 885 t.Errorf("subshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want) 886 } 887 if want, got := c>>s-d, rsbshiftRAreg_ssa(c, d, s); got != want { 888 t.Errorf("rsbshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want) 889 } 890 if want, got := c&(d>>s), andshiftRAreg_ssa(c, d, s); got != want { 891 t.Errorf("andshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want) 892 } 893 if want, got := c|d>>s, orshiftRAreg_ssa(c, d, s); got != want { 894 t.Errorf("orshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want) 895 } 896 if want, got := c^d>>s, xorshiftRAreg_ssa(c, d, s); got != want { 897 t.Errorf("xorshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want) 898 } 899 if want, got := c&^(d>>s), bicshiftRAreg_ssa(c, d, s); got != want { 900 t.Errorf("bicshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want) 901 } 902 if want, got := ^(d >> s), notshiftRAreg_ssa(d, s); got != want { 903 t.Errorf("notshiftRAreg_ssa(-42, 3) = %d want %d", got, want) 904 } 905 } 906 907 // TestArithmetic tests that both backends have the same result for arithmetic expressions. 908 func TestArithmetic(t *testing.T) { 909 test64BitConstMult(t) 910 test64BitConstAdd(t) 911 testRegallocCVSpill(t) 912 testSubqToNegq(t) 913 testBitwiseLogic(t) 914 testOcom(t) 915 testLrot(t) 916 testShiftCX(t) 917 testSubConst(t) 918 testOverflowConstShift(t) 919 testArithConstShift(t) 920 testArithRshConst(t) 921 testLargeConst(t) 922 testLoadCombine(t) 923 testLoadSymCombine(t) 924 testShiftRemoval(t) 925 testShiftedOps(t) 926 testDivFixUp(t) 927 } 928 929 // testDivFixUp ensures that signed division fix-ups are being generated. 930 func testDivFixUp(t *testing.T) { 931 defer func() { 932 if r := recover(); r != nil { 933 t.Error("testDivFixUp failed") 934 if e, ok := r.(runtime.Error); ok { 935 t.Logf("%v\n", e.Error()) 936 } 937 } 938 }() 939 var w int8 = -128 940 var x int16 = -32768 941 var y int32 = -2147483648 942 var z int64 = -9223372036854775808 943 944 for i := -5; i < 0; i++ { 945 g8 = w / int8(i) 946 g16 = x / int16(i) 947 g32 = y / int32(i) 948 g64 = z / int64(i) 949 g8 = w % int8(i) 950 g16 = x % int16(i) 951 g32 = y % int32(i) 952 g64 = z % int64(i) 953 } 954 }