Source file src/cmd/compile/internal/test/testdata/arith_test.go

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

View as plain text