Source file test/codegen/comparisons.go

     1  // asmcheck
     2  
     3  // Copyright 2018 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  package codegen
     8  
     9  import "unsafe"
    10  
    11  // This file contains code generation tests related to the comparison
    12  // operators.
    13  
    14  // -------------- //
    15  //    Equality    //
    16  // -------------- //
    17  
    18  // Check that compare to constant string use 2/4/8 byte compares
    19  
    20  func CompareString1(s string) bool {
    21  	// amd64:`CMPW\t\(.*\), [$]`
    22  	// arm64:`MOVHU\t\(.*\), [R]`,`MOVD\t[$]`,`CMPW\tR`
    23  	// ppc64le:`MOVHZ\t\(.*\), [R]`,`CMPW\t.*, [$]`
    24  	// s390x:`MOVHBR\t\(.*\), [R]`,`CMPW\t.*, [$]`
    25  	return s == "xx"
    26  }
    27  
    28  func CompareString2(s string) bool {
    29  	// amd64:`CMPL\t\(.*\), [$]`
    30  	// arm64:`MOVWU\t\(.*\), [R]`,`CMPW\t.*, [R]`
    31  	// ppc64le:`MOVWZ\t\(.*\), [R]`,`CMPW\t.*, [R]`
    32  	// s390x:`MOVWBR\t\(.*\), [R]`,`CMPW\t.*, [$]`
    33  	return s == "xxxx"
    34  }
    35  
    36  func CompareString3(s string) bool {
    37  	// amd64:`CMPQ\t\(.*\), [A-Z]`
    38  	// arm64:-`CMPW\t`
    39  	// ppc64x:-`CMPW\t`
    40  	// s390x:-`CMPW\t`
    41  	return s == "xxxxxxxx"
    42  }
    43  
    44  // Check that arrays compare use 2/4/8 byte compares
    45  
    46  func CompareArray1(a, b [2]byte) bool {
    47  	// amd64:`CMPW\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
    48  	// arm64:-`MOVBU\t`
    49  	// ppc64le:-`MOVBZ\t`
    50  	// s390x:-`MOVBZ\t`
    51  	return a == b
    52  }
    53  
    54  func CompareArray2(a, b [3]uint16) bool {
    55  	// amd64:`CMPL\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
    56  	// amd64:`CMPW\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
    57  	return a == b
    58  }
    59  
    60  func CompareArray3(a, b [3]int16) bool {
    61  	// amd64:`CMPL\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
    62  	// amd64:`CMPW\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
    63  	return a == b
    64  }
    65  
    66  func CompareArray4(a, b [12]int8) bool {
    67  	// amd64:`CMPQ\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
    68  	// amd64:`CMPL\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
    69  	return a == b
    70  }
    71  
    72  func CompareArray5(a, b [15]byte) bool {
    73  	// amd64:`CMPQ\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
    74  	return a == b
    75  }
    76  
    77  // This was a TODO in mapaccess1_faststr
    78  func CompareArray6(a, b unsafe.Pointer) bool {
    79  	// amd64:`CMPL\t\(.*\), [A-Z]`
    80  	// arm64:`MOVWU\t\(.*\), [R]`,`CMPW\t.*, [R]`
    81  	// ppc64le:`MOVWZ\t\(.*\), [R]`,`CMPW\t.*, [R]`
    82  	// s390x:`MOVWBR\t\(.*\), [R]`,`CMPW\t.*, [R]`
    83  	return *((*[4]byte)(a)) != *((*[4]byte)(b))
    84  }
    85  
    86  // Check that some structs generate 2/4/8 byte compares.
    87  
    88  type T1 struct {
    89  	a [8]byte
    90  }
    91  
    92  func CompareStruct1(s1, s2 T1) bool {
    93  	// amd64:`CMPQ\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
    94  	// amd64:-`CALL`
    95  	return s1 == s2
    96  }
    97  
    98  type T2 struct {
    99  	a [16]byte
   100  }
   101  
   102  func CompareStruct2(s1, s2 T2) bool {
   103  	// amd64:`CMPQ\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
   104  	// amd64:-`CALL`
   105  	return s1 == s2
   106  }
   107  
   108  // Assert that a memequal call is still generated when
   109  // inlining would increase binary size too much.
   110  
   111  type T3 struct {
   112  	a [24]byte
   113  }
   114  
   115  func CompareStruct3(s1, s2 T3) bool {
   116  	// amd64:-`CMPQ\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
   117  	// amd64:`CALL`
   118  	return s1 == s2
   119  }
   120  
   121  type T4 struct {
   122  	a [32]byte
   123  }
   124  
   125  func CompareStruct4(s1, s2 T4) bool {
   126  	// amd64:-`CMPQ\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
   127  	// amd64:`CALL`
   128  	return s1 == s2
   129  }
   130  
   131  // -------------- //
   132  //    Ordering    //
   133  // -------------- //
   134  
   135  // Test that LEAQ/ADDQconst are folded into SETx ops
   136  
   137  var r bool
   138  
   139  func CmpFold(x uint32) {
   140  	// amd64:`SETHI\t.*\(SB\)`
   141  	r = x > 4
   142  }
   143  
   144  // Test that direct comparisons with memory are generated when
   145  // possible
   146  
   147  func CmpMem1(p int, q *int) bool {
   148  	// amd64:`CMPQ\t\(.*\), [A-Z]`
   149  	return p < *q
   150  }
   151  
   152  func CmpMem2(p *int, q int) bool {
   153  	// amd64:`CMPQ\t\(.*\), [A-Z]`
   154  	return *p < q
   155  }
   156  
   157  func CmpMem3(p *int) bool {
   158  	// amd64:`CMPQ\t\(.*\), [$]7`
   159  	return *p < 7
   160  }
   161  
   162  func CmpMem4(p *int) bool {
   163  	// amd64:`CMPQ\t\(.*\), [$]7`
   164  	return 7 < *p
   165  }
   166  
   167  func CmpMem5(p **int) {
   168  	// amd64:`CMPL\truntime.writeBarrier\(SB\), [$]0`
   169  	*p = nil
   170  }
   171  
   172  func CmpMem6(a []int) int {
   173  	// 386:`CMPL\s8\([A-Z]+\),`
   174  	// amd64:`CMPQ\s16\([A-Z]+\),`
   175  	if a[1] > a[2] {
   176  		return 1
   177  	} else {
   178  		return 2
   179  	}
   180  }
   181  
   182  // Check tbz/tbnz are generated when comparing against zero on arm64
   183  
   184  func CmpZero1(a int32, ptr *int) {
   185  	if a < 0 { // arm64:"TBZ"
   186  		*ptr = 0
   187  	}
   188  }
   189  
   190  func CmpZero2(a int64, ptr *int) {
   191  	if a < 0 { // arm64:"TBZ"
   192  		*ptr = 0
   193  	}
   194  }
   195  
   196  func CmpZero3(a int32, ptr *int) {
   197  	if a >= 0 { // arm64:"TBNZ"
   198  		*ptr = 0
   199  	}
   200  }
   201  
   202  func CmpZero4(a int64, ptr *int) {
   203  	if a >= 0 { // arm64:"TBNZ"
   204  		*ptr = 0
   205  	}
   206  }
   207  
   208  func CmpToZero(a, b, d int32, e, f int64, deOptC0, deOptC1 bool) int32 {
   209  	// arm:`TST`,-`AND`
   210  	// arm64:`TSTW`,-`AND`
   211  	// 386:`TESTL`,-`ANDL`
   212  	// amd64:`TESTL`,-`ANDL`
   213  	c0 := a&b < 0
   214  	// arm:`CMN`,-`ADD`
   215  	// arm64:`CMNW`,-`ADD`
   216  	c1 := a+b < 0
   217  	// arm:`TEQ`,-`XOR`
   218  	c2 := a^b < 0
   219  	// arm64:`TST`,-`AND`
   220  	// amd64:`TESTQ`,-`ANDQ`
   221  	c3 := e&f < 0
   222  	// arm64:`CMN`,-`ADD`
   223  	c4 := e+f < 0
   224  	// not optimized to single CMNW/CMN due to further use of b+d
   225  	// arm64:`ADD`,-`CMNW`
   226  	// arm:`ADD`,-`CMN`
   227  	c5 := b+d == 0
   228  	// not optimized to single TSTW/TST due to further use of a&d
   229  	// arm64:`AND`,-`TSTW`
   230  	// arm:`AND`,-`TST`
   231  	// 386:`ANDL`
   232  	c6 := a&d >= 0
   233  	// arm64:`TST\sR[0-9]+<<3,\sR[0-9]+`
   234  	c7 := e&(f<<3) < 0
   235  	// arm64:`CMN\sR[0-9]+<<3,\sR[0-9]+`
   236  	c8 := e+(f<<3) < 0
   237  	// arm64:`TST\sR[0-9],\sR[0-9]+`
   238  	c9 := e&(-19) < 0
   239  	if c0 {
   240  		return 1
   241  	} else if c1 {
   242  		return 2
   243  	} else if c2 {
   244  		return 3
   245  	} else if c3 {
   246  		return 4
   247  	} else if c4 {
   248  		return 5
   249  	} else if c5 {
   250  		return 6
   251  	} else if c6 {
   252  		return 7
   253  	} else if c7 {
   254  		return 9
   255  	} else if c8 {
   256  		return 10
   257  	} else if c9 {
   258  		return 11
   259  	} else if deOptC0 {
   260  		return b + d
   261  	} else if deOptC1 {
   262  		return a & d
   263  	} else {
   264  		return 0
   265  	}
   266  }
   267  
   268  func CmpLogicalToZero(a, b, c uint32, d, e uint64) uint64 {
   269  
   270  	// ppc64x:"ANDCC",-"CMPW"
   271  	// wasm:"I64Eqz",-"I32Eqz",-"I64ExtendI32U",-"I32WrapI64"
   272  	if a&63 == 0 {
   273  		return 1
   274  	}
   275  
   276  	// ppc64x:"ANDCC",-"CMP"
   277  	// wasm:"I64Eqz",-"I32Eqz",-"I64ExtendI32U",-"I32WrapI64"
   278  	if d&255 == 0 {
   279  		return 1
   280  	}
   281  
   282  	// ppc64x:"ANDCC",-"CMP"
   283  	// wasm:"I64Eqz",-"I32Eqz",-"I64ExtendI32U",-"I32WrapI64"
   284  	if d&e == 0 {
   285  		return 1
   286  	}
   287  	// ppc64x:"ORCC",-"CMP"
   288  	// wasm:"I64Eqz",-"I32Eqz",-"I64ExtendI32U",-"I32WrapI64"
   289  	if d|e == 0 {
   290  		return 1
   291  	}
   292  
   293  	// ppc64x:"XORCC",-"CMP"
   294  	// wasm:"I64Eqz","I32Eqz",-"I64ExtendI32U",-"I32WrapI64"
   295  	if e^d == 0 {
   296  		return 1
   297  	}
   298  	return 0
   299  }
   300  
   301  // The following CmpToZero_ex* check that cmp|cmn with bmi|bpl are generated for
   302  // 'comparing to zero' expressions
   303  
   304  // var + const
   305  // 'x-const' might be canonicalized to 'x+(-const)', so we check both
   306  // CMN and CMP for subtraction expressions to make the pattern robust.
   307  func CmpToZero_ex1(a int64, e int32) int {
   308  	// arm64:`CMN`,-`ADD`,`(BMI|BPL)`
   309  	if a+3 < 0 {
   310  		return 1
   311  	}
   312  
   313  	// arm64:`CMN`,-`ADD`,`BEQ`,`(BMI|BPL)`
   314  	if a+5 <= 0 {
   315  		return 1
   316  	}
   317  
   318  	// arm64:`CMN`,-`ADD`,`(BMI|BPL)`
   319  	if a+13 >= 0 {
   320  		return 2
   321  	}
   322  
   323  	// arm64:`CMP|CMN`,-`(ADD|SUB)`,`(BMI|BPL)`
   324  	if a-7 < 0 {
   325  		return 3
   326  	}
   327  
   328  	// arm64:`SUB`,`TBZ`
   329  	if a-11 >= 0 {
   330  		return 4
   331  	}
   332  
   333  	// arm64:`SUB`,`CMP`,`BGT`
   334  	if a-19 > 0 {
   335  		return 4
   336  	}
   337  
   338  	// arm64:`CMNW`,-`ADDW`,`(BMI|BPL)`
   339  	// arm:`CMN`,-`ADD`,`(BMI|BPL)`
   340  	if e+3 < 0 {
   341  		return 5
   342  	}
   343  
   344  	// arm64:`CMNW`,-`ADDW`,`(BMI|BPL)`
   345  	// arm:`CMN`,-`ADD`,`(BMI|BPL)`
   346  	if e+13 >= 0 {
   347  		return 6
   348  	}
   349  
   350  	// arm64:`CMPW|CMNW`,`(BMI|BPL)`
   351  	// arm:`CMP|CMN`, -`(ADD|SUB)`, `(BMI|BPL)`
   352  	if e-7 < 0 {
   353  		return 7
   354  	}
   355  
   356  	// arm64:`SUB`,`TBNZ`
   357  	// arm:`CMP|CMN`, -`(ADD|SUB)`, `(BMI|BPL)`
   358  	if e-11 >= 0 {
   359  		return 8
   360  	}
   361  
   362  	return 0
   363  }
   364  
   365  // var + var
   366  // TODO: optimize 'var - var'
   367  func CmpToZero_ex2(a, b, c int64, e, f, g int32) int {
   368  	// arm64:`CMN`,-`ADD`,`(BMI|BPL)`
   369  	if a+b < 0 {
   370  		return 1
   371  	}
   372  
   373  	// arm64:`CMN`,-`ADD`,`BEQ`,`(BMI|BPL)`
   374  	if a+c <= 0 {
   375  		return 1
   376  	}
   377  
   378  	// arm64:`CMN`,-`ADD`,`(BMI|BPL)`
   379  	if b+c >= 0 {
   380  		return 2
   381  	}
   382  
   383  	// arm64:`CMNW`,-`ADDW`,`(BMI|BPL)`
   384  	// arm:`CMN`,-`ADD`,`(BMI|BPL)`
   385  	if e+f < 0 {
   386  		return 5
   387  	}
   388  
   389  	// arm64:`CMNW`,-`ADDW`,`(BMI|BPL)`
   390  	// arm:`CMN`,-`ADD`,`(BMI|BPL)`
   391  	if f+g >= 0 {
   392  		return 6
   393  	}
   394  	return 0
   395  }
   396  
   397  // var + var*var
   398  func CmpToZero_ex3(a, b, c, d int64, e, f, g, h int32) int {
   399  	// arm64:`CMN`,-`MADD`,`MUL`,`(BMI|BPL)`
   400  	if a+b*c < 0 {
   401  		return 1
   402  	}
   403  
   404  	// arm64:`CMN`,-`MADD`,`MUL`,`(BMI|BPL)`
   405  	if b+c*d >= 0 {
   406  		return 2
   407  	}
   408  
   409  	// arm64:`CMNW`,-`MADDW`,`MULW`,`BEQ`,`(BMI|BPL)`
   410  	// arm:`CMN`,-`MULA`,`MUL`,`BEQ`,`(BMI|BPL)`
   411  	if e+f*g > 0 {
   412  		return 5
   413  	}
   414  
   415  	// arm64:`CMNW`,-`MADDW`,`MULW`,`BEQ`,`(BMI|BPL)`
   416  	// arm:`CMN`,-`MULA`,`MUL`,`BEQ`,`(BMI|BPL)`
   417  	if f+g*h <= 0 {
   418  		return 6
   419  	}
   420  	return 0
   421  }
   422  
   423  // var - var*var
   424  func CmpToZero_ex4(a, b, c, d int64, e, f, g, h int32) int {
   425  	// arm64:`CMP`,-`MSUB`,`MUL`,`BEQ`,`(BMI|BPL)`
   426  	if a-b*c > 0 {
   427  		return 1
   428  	}
   429  
   430  	// arm64:`CMP`,-`MSUB`,`MUL`,`(BMI|BPL)`
   431  	if b-c*d >= 0 {
   432  		return 2
   433  	}
   434  
   435  	// arm64:`CMPW`,-`MSUBW`,`MULW`,`(BMI|BPL)`
   436  	if e-f*g < 0 {
   437  		return 5
   438  	}
   439  
   440  	// arm64:`CMPW`,-`MSUBW`,`MULW`,`(BMI|BPL)`
   441  	if f-g*h >= 0 {
   442  		return 6
   443  	}
   444  	return 0
   445  }
   446  
   447  func CmpToZero_ex5(e, f int32, u uint32) int {
   448  	// arm:`CMN`,-`ADD`,`BEQ`,`(BMI|BPL)`
   449  	if e+f<<1 > 0 {
   450  		return 1
   451  	}
   452  
   453  	// arm:`CMP`,-`SUB`,`(BMI|BPL)`
   454  	if f-int32(u>>2) >= 0 {
   455  		return 2
   456  	}
   457  	return 0
   458  }
   459  
   460  func UintLtZero(a uint8, b uint16, c uint32, d uint64) int {
   461  	// amd64: -`(TESTB|TESTW|TESTL|TESTQ|JCC|JCS)`
   462  	// arm64: -`(CMPW|CMP|BHS|BLO)`
   463  	if a < 0 || b < 0 || c < 0 || d < 0 {
   464  		return 1
   465  	}
   466  	return 0
   467  }
   468  
   469  func UintGeqZero(a uint8, b uint16, c uint32, d uint64) int {
   470  	// amd64: -`(TESTB|TESTW|TESTL|TESTQ|JCS|JCC)`
   471  	// arm64: -`(CMPW|CMP|BLO|BHS)`
   472  	if a >= 0 || b >= 0 || c >= 0 || d >= 0 {
   473  		return 1
   474  	}
   475  	return 0
   476  }
   477  
   478  func UintGtZero(a uint8, b uint16, c uint32, d uint64) int {
   479  	// arm64: `(CBN?ZW)`, `(CBN?Z[^W])`, -`(CMPW|CMP|BLS|BHI)`
   480  	if a > 0 || b > 0 || c > 0 || d > 0 {
   481  		return 1
   482  	}
   483  	return 0
   484  }
   485  
   486  func UintLeqZero(a uint8, b uint16, c uint32, d uint64) int {
   487  	// arm64: `(CBN?ZW)`, `(CBN?Z[^W])`, -`(CMPW|CMP|BHI|BLS)`
   488  	if a <= 0 || b <= 0 || c <= 0 || d <= 0 {
   489  		return 1
   490  	}
   491  	return 0
   492  }
   493  
   494  func UintLtOne(a uint8, b uint16, c uint32, d uint64) int {
   495  	// arm64: `(CBN?ZW)`, `(CBN?Z[^W])`, -`(CMPW|CMP|BHS|BLO)`
   496  	if a < 1 || b < 1 || c < 1 || d < 1 {
   497  		return 1
   498  	}
   499  	return 0
   500  }
   501  
   502  func UintGeqOne(a uint8, b uint16, c uint32, d uint64) int {
   503  	// arm64: `(CBN?ZW)`, `(CBN?Z[^W])`, -`(CMPW|CMP|BLO|BHS)`
   504  	if a >= 1 || b >= 1 || c >= 1 || d >= 1 {
   505  		return 1
   506  	}
   507  	return 0
   508  }
   509  
   510  func CmpToZeroU_ex1(a uint8, b uint16, c uint32, d uint64) int {
   511  	// wasm:"I64Eqz"-"I64LtU"
   512  	if 0 < a {
   513  		return 1
   514  	}
   515  	// wasm:"I64Eqz"-"I64LtU"
   516  	if 0 < b {
   517  		return 1
   518  	}
   519  	// wasm:"I64Eqz"-"I64LtU"
   520  	if 0 < c {
   521  		return 1
   522  	}
   523  	// wasm:"I64Eqz"-"I64LtU"
   524  	if 0 < d {
   525  		return 1
   526  	}
   527  	return 0
   528  }
   529  
   530  func CmpToZeroU_ex2(a uint8, b uint16, c uint32, d uint64) int {
   531  	// wasm:"I64Eqz"-"I64LeU"
   532  	if a <= 0 {
   533  		return 1
   534  	}
   535  	// wasm:"I64Eqz"-"I64LeU"
   536  	if b <= 0 {
   537  		return 1
   538  	}
   539  	// wasm:"I64Eqz"-"I64LeU"
   540  	if c <= 0 {
   541  		return 1
   542  	}
   543  	// wasm:"I64Eqz"-"I64LeU"
   544  	if d <= 0 {
   545  		return 1
   546  	}
   547  	return 0
   548  }
   549  
   550  func CmpToOneU_ex1(a uint8, b uint16, c uint32, d uint64) int {
   551  	// wasm:"I64Eqz"-"I64LtU"
   552  	if a < 1 {
   553  		return 1
   554  	}
   555  	// wasm:"I64Eqz"-"I64LtU"
   556  	if b < 1 {
   557  		return 1
   558  	}
   559  	// wasm:"I64Eqz"-"I64LtU"
   560  	if c < 1 {
   561  		return 1
   562  	}
   563  	// wasm:"I64Eqz"-"I64LtU"
   564  	if d < 1 {
   565  		return 1
   566  	}
   567  	return 0
   568  }
   569  
   570  func CmpToOneU_ex2(a uint8, b uint16, c uint32, d uint64) int {
   571  	// wasm:"I64Eqz"-"I64LeU"
   572  	if 1 <= a {
   573  		return 1
   574  	}
   575  	// wasm:"I64Eqz"-"I64LeU"
   576  	if 1 <= b {
   577  		return 1
   578  	}
   579  	// wasm:"I64Eqz"-"I64LeU"
   580  	if 1 <= c {
   581  		return 1
   582  	}
   583  	// wasm:"I64Eqz"-"I64LeU"
   584  	if 1 <= d {
   585  		return 1
   586  	}
   587  	return 0
   588  }
   589  
   590  // Check that small memequals are replaced with eq instructions
   591  
   592  func equalConstString1() bool {
   593  	a := string("A")
   594  	b := string("Z")
   595  	// amd64:-".*memequal"
   596  	// arm64:-".*memequal"
   597  	// ppc64x:-".*memequal"
   598  	return a == b
   599  }
   600  
   601  func equalVarString1(a string) bool {
   602  	b := string("Z")
   603  	// amd64:-".*memequal"
   604  	// arm64:-".*memequal"
   605  	// ppc64x:-".*memequal"
   606  	return a[:1] == b
   607  }
   608  
   609  func equalConstString2() bool {
   610  	a := string("AA")
   611  	b := string("ZZ")
   612  	// amd64:-".*memequal"
   613  	// arm64:-".*memequal"
   614  	// ppc64x:-".*memequal"
   615  	return a == b
   616  }
   617  
   618  func equalVarString2(a string) bool {
   619  	b := string("ZZ")
   620  	// amd64:-".*memequal"
   621  	// arm64:-".*memequal"
   622  	// ppc64x:-".*memequal"
   623  	return a[:2] == b
   624  }
   625  
   626  func equalConstString4() bool {
   627  	a := string("AAAA")
   628  	b := string("ZZZZ")
   629  	// amd64:-".*memequal"
   630  	// arm64:-".*memequal"
   631  	// ppc64x:-".*memequal"
   632  	return a == b
   633  }
   634  
   635  func equalVarString4(a string) bool {
   636  	b := string("ZZZZ")
   637  	// amd64:-".*memequal"
   638  	// arm64:-".*memequal"
   639  	// ppc64x:-".*memequal"
   640  	return a[:4] == b
   641  }
   642  
   643  func equalConstString8() bool {
   644  	a := string("AAAAAAAA")
   645  	b := string("ZZZZZZZZ")
   646  	// amd64:-".*memequal"
   647  	// arm64:-".*memequal"
   648  	// ppc64x:-".*memequal"
   649  	return a == b
   650  }
   651  
   652  func equalVarString8(a string) bool {
   653  	b := string("ZZZZZZZZ")
   654  	// amd64:-".*memequal"
   655  	// arm64:-".*memequal"
   656  	// ppc64x:-".*memequal"
   657  	return a[:8] == b
   658  }
   659  
   660  func cmpToCmn(a, b, c, d int) int {
   661  	var c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11 int
   662  	// arm64:`CMN`,-`CMP`
   663  	if a < -8 {
   664  		c1 = 1
   665  	}
   666  	// arm64:`CMN`,-`CMP`
   667  	if a+1 == 0 {
   668  		c2 = 1
   669  	}
   670  	// arm64:`CMN`,-`CMP`
   671  	if a+3 != 0 {
   672  		c3 = 1
   673  	}
   674  	// arm64:`CMN`,-`CMP`
   675  	if a+b == 0 {
   676  		c4 = 1
   677  	}
   678  	// arm64:`CMN`,-`CMP`
   679  	if b+c != 0 {
   680  		c5 = 1
   681  	}
   682  	// arm64:`CMN`,-`CMP`
   683  	if a == -c {
   684  		c6 = 1
   685  	}
   686  	// arm64:`CMN`,-`CMP`
   687  	if b != -d {
   688  		c7 = 1
   689  	}
   690  	// arm64:`CMN`,-`CMP`
   691  	if a*b+c == 0 {
   692  		c8 = 1
   693  	}
   694  	// arm64:`CMN`,-`CMP`
   695  	if a*c+b != 0 {
   696  		c9 = 1
   697  	}
   698  	// arm64:`CMP`,-`CMN`
   699  	if b*c-a == 0 {
   700  		c10 = 1
   701  	}
   702  	// arm64:`CMP`,-`CMN`
   703  	if a*d-b != 0 {
   704  		c11 = 1
   705  	}
   706  	return c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 + c9 + c10 + c11
   707  }
   708  
   709  func cmpToCmnLessThan(a, b, c, d int) int {
   710  	var c1, c2, c3, c4 int
   711  	// arm64:`CMN`,`CSET\tMI`,-`CMP`
   712  	if a+1 < 0 {
   713  		c1 = 1
   714  	}
   715  	// arm64:`CMN`,`CSET\tMI`,-`CMP`
   716  	if a+b < 0 {
   717  		c2 = 1
   718  	}
   719  	// arm64:`CMN`,`CSET\tMI`,-`CMP`
   720  	if a*b+c < 0 {
   721  		c3 = 1
   722  	}
   723  	// arm64:`CMP`,`CSET\tMI`,-`CMN`
   724  	if a-b*c < 0 {
   725  		c4 = 1
   726  	}
   727  	return c1 + c2 + c3 + c4
   728  }
   729  
   730  func cmpToCmnGreaterThanEqual(a, b, c, d int) int {
   731  	var c1, c2, c3, c4 int
   732  	// arm64:`CMN`,`CSET\tPL`,-`CMP`
   733  	if a+1 >= 0 {
   734  		c1 = 1
   735  	}
   736  	// arm64:`CMN`,`CSET\tPL`,-`CMP`
   737  	if a+b >= 0 {
   738  		c2 = 1
   739  	}
   740  	// arm64:`CMN`,`CSET\tPL`,-`CMP`
   741  	if a*b+c >= 0 {
   742  		c3 = 1
   743  	}
   744  	// arm64:`CMP`,`CSET\tPL`,-`CMN`
   745  	if a-b*c >= 0 {
   746  		c4 = 1
   747  	}
   748  	return c1 + c2 + c3 + c4
   749  }
   750  
   751  func cmp1(val string) bool {
   752  	var z string
   753  	// amd64:-".*memequal"
   754  	return z == val
   755  }
   756  
   757  func cmp2(val string) bool {
   758  	var z string
   759  	// amd64:-".*memequal"
   760  	return val == z
   761  }
   762  
   763  func cmp3(val string) bool {
   764  	z := "food"
   765  	// amd64:-".*memequal"
   766  	return z == val
   767  }
   768  
   769  func cmp4(val string) bool {
   770  	z := "food"
   771  	// amd64:-".*memequal"
   772  	return val == z
   773  }
   774  
   775  func cmp5[T comparable](val T) bool {
   776  	var z T
   777  	// amd64:-".*memequal"
   778  	return z == val
   779  }
   780  
   781  func cmp6[T comparable](val T) bool {
   782  	var z T
   783  	// amd64:-".*memequal"
   784  	return val == z
   785  }
   786  
   787  func cmp7() {
   788  	cmp5[string]("") // force instantiation
   789  	cmp6[string]("") // force instantiation
   790  }
   791  
   792  type Point struct {
   793  	X, Y int
   794  }
   795  
   796  // invertLessThanNoov checks (LessThanNoov (InvertFlags x)) is lowered as
   797  // CMP, CSET, CSEL instruction sequence. InvertFlags are only generated under
   798  // certain conditions, see canonLessThan, so if the code below does not
   799  // generate an InvertFlags OP, this check may fail.
   800  func invertLessThanNoov(p1, p2, p3 Point) bool {
   801  	// arm64:`CMP`,`CSET`,`CSEL`
   802  	return (p1.X-p3.X)*(p2.Y-p3.Y)-(p2.X-p3.X)*(p1.Y-p3.Y) < 0
   803  }
   804  

View as plain text