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