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  }