Source file test/codegen/fuse.go

     1  // asmcheck
     2  
     3  // Copyright 2019 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 "math"
    10  
    11  // Notes:
    12  // - these examples use channels to provide a source of
    13  //   unknown values that cannot be optimized away
    14  // - these examples use for loops to force branches
    15  //   backward (predicted taken)
    16  
    17  // ---------------------------------- //
    18  // signed integer range (conjunction) //
    19  // ---------------------------------- //
    20  
    21  func si1c(c <-chan int64) {
    22  	// amd64:"CMPQ .+, [$]256"
    23  	// s390x:"CLGIJ [$]12, R[0-9]+, [$]255"
    24  	for x := <-c; x >= 0 && x < 256; x = <-c {
    25  	}
    26  }
    27  
    28  func si2c(c <-chan int32) {
    29  	// amd64:"CMPL .+, [$]256"
    30  	// s390x:"CLIJ [$]12, R[0-9]+, [$]255"
    31  	for x := <-c; x >= 0 && x < 256; x = <-c {
    32  	}
    33  }
    34  
    35  func si3c(c <-chan int16) {
    36  	// amd64:"CMPW .+, [$]256"
    37  	// s390x:"CLIJ [$]12, R[0-9]+, [$]255"
    38  	for x := <-c; x >= 0 && x < 256; x = <-c {
    39  	}
    40  }
    41  
    42  func si4c(c <-chan int8) {
    43  	// amd64:"CMPB .+, [$]10"
    44  	// s390x:"CLIJ [$]4, R[0-9]+, [$]10"
    45  	for x := <-c; x >= 0 && x < 10; x = <-c {
    46  	}
    47  }
    48  
    49  func si5c(c <-chan int64) {
    50  	// amd64:"CMPQ .+, [$]251" "ADDQ [$]-5,"
    51  	// s390x:"CLGIJ [$]4, R[0-9]+, [$]251" "ADD [$]-5,"
    52  	for x := <-c; x < 256 && x > 4; x = <-c {
    53  	}
    54  }
    55  
    56  func si6c(c <-chan int32) {
    57  	// amd64:"CMPL .+, [$]255" "DECL "
    58  	// s390x:"CLIJ [$]12, R[0-9]+, [$]255" "ADDW [$]-1,"
    59  	for x := <-c; x > 0 && x <= 256; x = <-c {
    60  	}
    61  }
    62  
    63  func si7c(c <-chan int16) {
    64  	// amd64:"CMPW .+, [$]60" "ADDL [$]10,"
    65  	// s390x:"CLIJ [$]12, R[0-9]+, [$]60" "ADDW [$]10,"
    66  	for x := <-c; x >= -10 && x <= 50; x = <-c {
    67  	}
    68  }
    69  
    70  func si8c(c <-chan int8) {
    71  	// amd64:"CMPB .+, [$]126" "ADDL [$]126,"
    72  	// s390x:"CLIJ [$]4, R[0-9]+, [$]126" "ADDW [$]126,"
    73  	for x := <-c; x >= -126 && x < 0; x = <-c {
    74  	}
    75  }
    76  
    77  // ---------------------------------- //
    78  // signed integer range (disjunction) //
    79  // ---------------------------------- //
    80  
    81  func si1d(c <-chan int64) {
    82  	// amd64:"CMPQ .+, [$]256"
    83  	// s390x:"CLGIJ [$]2, R[0-9]+, [$]255"
    84  	for x := <-c; x < 0 || x >= 256; x = <-c {
    85  	}
    86  }
    87  
    88  func si2d(c <-chan int32) {
    89  	// amd64:"CMPL .+, [$]256"
    90  	// s390x:"CLIJ [$]2, R[0-9]+, [$]255"
    91  	for x := <-c; x < 0 || x >= 256; x = <-c {
    92  	}
    93  }
    94  
    95  func si3d(c <-chan int16) {
    96  	// amd64:"CMPW .+, [$]256"
    97  	// s390x:"CLIJ [$]2, R[0-9]+, [$]255"
    98  	for x := <-c; x < 0 || x >= 256; x = <-c {
    99  	}
   100  }
   101  
   102  func si4d(c <-chan int8) {
   103  	// amd64:"CMPB .+, [$]10"
   104  	// s390x:"CLIJ [$]10, R[0-9]+, [$]10"
   105  	for x := <-c; x < 0 || x >= 10; x = <-c {
   106  	}
   107  }
   108  
   109  func si5d(c <-chan int64) {
   110  	// amd64:"CMPQ .+, [$]251" "ADDQ [$]-5,"
   111  	// s390x:"CLGIJ [$]10, R[0-9]+, [$]251" "ADD [$]-5,"
   112  	for x := <-c; x >= 256 || x <= 4; x = <-c {
   113  	}
   114  }
   115  
   116  func si6d(c <-chan int32) {
   117  	// amd64:"CMPL .+, [$]255" "DECL "
   118  	// s390x:"CLIJ [$]2, R[0-9]+, [$]255" "ADDW [$]-1,"
   119  	for x := <-c; x <= 0 || x > 256; x = <-c {
   120  	}
   121  }
   122  
   123  func si7d(c <-chan int16) {
   124  	// amd64:"CMPW .+, [$]60" "ADDL [$]10,"
   125  	// s390x:"CLIJ [$]2, R[0-9]+, [$]60" "ADDW [$]10,"
   126  	for x := <-c; x < -10 || x > 50; x = <-c {
   127  	}
   128  }
   129  
   130  func si8d(c <-chan int8) {
   131  	// amd64:"CMPB .+, [$]126" "ADDL [$]126,"
   132  	// s390x:"CLIJ [$]10, R[0-9]+, [$]126" "ADDW [$]126,"
   133  	for x := <-c; x < -126 || x >= 0; x = <-c {
   134  	}
   135  }
   136  
   137  // ------------------------------------ //
   138  // unsigned integer range (conjunction) //
   139  // ------------------------------------ //
   140  
   141  func ui1c(c <-chan uint64) {
   142  	// amd64:"CMPQ .+, [$]251" "ADDQ [$]-5,"
   143  	// s390x:"CLGIJ [$]4, R[0-9]+, [$]251" "ADD [$]-5,"
   144  	for x := <-c; x < 256 && x > 4; x = <-c {
   145  	}
   146  }
   147  
   148  func ui2c(c <-chan uint32) {
   149  	// amd64:"CMPL .+, [$]255" "DECL "
   150  	// s390x:"CLIJ [$]12, R[0-9]+, [$]255" "ADDW [$]-1,"
   151  	for x := <-c; x > 0 && x <= 256; x = <-c {
   152  	}
   153  }
   154  
   155  func ui3c(c <-chan uint16) {
   156  	// amd64:"CMPW .+, [$]40" "ADDL [$]-10,"
   157  	// s390x:"CLIJ [$]12, R[0-9]+, [$]40" "ADDW [$]-10,"
   158  	for x := <-c; x >= 10 && x <= 50; x = <-c {
   159  	}
   160  }
   161  
   162  func ui4c(c <-chan uint8) {
   163  	// amd64:"CMPB .+, [$]2" "ADDL [$]-126,"
   164  	// s390x:"CLIJ [$]4, R[0-9]+, [$]2" "ADDW [$]-126,"
   165  	for x := <-c; x >= 126 && x < 128; x = <-c {
   166  	}
   167  }
   168  
   169  // ------------------------------------ //
   170  // unsigned integer range (disjunction) //
   171  // ------------------------------------ //
   172  
   173  func ui1d(c <-chan uint64) {
   174  	// amd64:"CMPQ .+, [$]251" "ADDQ [$]-5,"
   175  	// s390x:"CLGIJ [$]10, R[0-9]+, [$]251" "ADD [$]-5,"
   176  	for x := <-c; x >= 256 || x <= 4; x = <-c {
   177  	}
   178  }
   179  
   180  func ui2d(c <-chan uint32) {
   181  	// amd64:"CMPL .+, [$]254" "ADDL [$]-2,"
   182  	// s390x:"CLIJ [$]2, R[0-9]+, [$]254" "ADDW [$]-2,"
   183  	for x := <-c; x <= 1 || x > 256; x = <-c {
   184  	}
   185  }
   186  
   187  func ui3d(c <-chan uint16) {
   188  	// amd64:"CMPW .+, [$]40" "ADDL [$]-10,"
   189  	// s390x:"CLIJ [$]2, R[0-9]+, [$]40" "ADDW [$]-10,"
   190  	for x := <-c; x < 10 || x > 50; x = <-c {
   191  	}
   192  }
   193  
   194  func ui4d(c <-chan uint8) {
   195  	// amd64:"CMPB .+, [$]2" "ADDL [$]-126,"
   196  	// s390x:"CLIJ [$]10, R[0-9]+, [$]2" "ADDW [$]-126,"
   197  	for x := <-c; x < 126 || x >= 128; x = <-c {
   198  	}
   199  }
   200  
   201  // ------------------------------------ //
   202  // single bit difference (conjunction)  //
   203  // ------------------------------------ //
   204  
   205  func sisbc64(c <-chan int64) {
   206  	// amd64: "ORQ [$]2,"
   207  	// riscv64: "ORI [$]2,"
   208  	for x := <-c; x != 4 && x != 6; x = <-c {
   209  	}
   210  }
   211  
   212  func sisbc32(c <-chan int32) {
   213  	// amd64: "ORL [$]4,"
   214  	// riscv64: "ORI [$]4,"
   215  	for x := <-c; x != -1 && x != -5; x = <-c {
   216  	}
   217  }
   218  
   219  func sisbc16(c <-chan int16) {
   220  	// amd64: "ORL [$]32,"
   221  	// riscv64: "ORI [$]32,"
   222  	for x := <-c; x != 16 && x != 48; x = <-c {
   223  	}
   224  }
   225  
   226  func sisbc8(c <-chan int8) {
   227  	// amd64: "ORL [$]16,"
   228  	// riscv64: "ORI [$]16,"
   229  	for x := <-c; x != -15 && x != -31; x = <-c {
   230  	}
   231  }
   232  
   233  func uisbc64(c <-chan uint64) {
   234  	// amd64: "ORQ [$]4,"
   235  	// riscv64: "ORI [$]4,"
   236  	for x := <-c; x != 1 && x != 5; x = <-c {
   237  	}
   238  }
   239  
   240  func uisbc32(c <-chan uint32) {
   241  	// amd64: "ORL [$]4,"
   242  	// riscv64: "ORI [$]4,"
   243  	for x := <-c; x != 2 && x != 6; x = <-c {
   244  	}
   245  }
   246  
   247  func uisbc16(c <-chan uint16) {
   248  	// amd64: "ORL [$]32,"
   249  	// riscv64: "ORI [$]32,"
   250  	for x := <-c; x != 16 && x != 48; x = <-c {
   251  	}
   252  }
   253  
   254  func uisbc8(c <-chan uint8) {
   255  	// amd64: "ORL [$]64,"
   256  	// riscv64: "ORI [$]64,"
   257  	for x := <-c; x != 64 && x != 0; x = <-c {
   258  	}
   259  }
   260  
   261  // ------------------------------------ //
   262  // single bit difference (disjunction)  //
   263  // ------------------------------------ //
   264  
   265  func sisbd64(c <-chan int64) {
   266  	// amd64: "ORQ [$]2,"
   267  	// riscv64: "ORI [$]2,"
   268  	for x := <-c; x == 4 || x == 6; x = <-c {
   269  	}
   270  }
   271  
   272  func sisbd32(c <-chan int32) {
   273  	// amd64: "ORL [$]4,"
   274  	// riscv64: "ORI [$]4,"
   275  	for x := <-c; x == -1 || x == -5; x = <-c {
   276  	}
   277  }
   278  
   279  func sisbd16(c <-chan int16) {
   280  	// amd64: "ORL [$]32,"
   281  	// riscv64: "ORI [$]32,"
   282  	for x := <-c; x == 16 || x == 48; x = <-c {
   283  	}
   284  }
   285  
   286  func sisbd8(c <-chan int8) {
   287  	// amd64: "ORL [$]16,"
   288  	// riscv64: "ORI [$]16,"
   289  	for x := <-c; x == -15 || x == -31; x = <-c {
   290  	}
   291  }
   292  
   293  func uisbd64(c <-chan uint64) {
   294  	// amd64: "ORQ [$]4,"
   295  	// riscv64: "ORI [$]4,"
   296  	for x := <-c; x == 1 || x == 5; x = <-c {
   297  	}
   298  }
   299  
   300  func uisbd32(c <-chan uint32) {
   301  	// amd64: "ORL [$]4,"
   302  	// riscv64: "ORI [$]4,"
   303  	for x := <-c; x == 2 || x == 6; x = <-c {
   304  	}
   305  }
   306  
   307  func uisbd16(c <-chan uint16) {
   308  	// amd64: "ORL [$]32,"
   309  	// riscv64: "ORI [$]32,"
   310  	for x := <-c; x == 16 || x == 48; x = <-c {
   311  	}
   312  }
   313  
   314  func uisbd8(c <-chan uint8) {
   315  	// amd64: "ORL [$]64,"
   316  	// riscv64: "ORI [$]64,"
   317  	for x := <-c; x == 64 || x == 0; x = <-c {
   318  	}
   319  }
   320  
   321  // -------------------------------------//
   322  // merge NaN checks                     //
   323  // ------------------------------------ //
   324  
   325  func f64NaNOrPosInf(c <-chan float64) {
   326  	// This test assumes IsInf(x, 1) is implemented as x > MaxFloat rather than x == Inf(1).
   327  
   328  	// amd64:"JCS" -"JNE" -"JPS" -"JPC"
   329  	// riscv64:"FCLASSD" -"FLED" -"FLTD" -"FNED" -"FEQD"
   330  	for x := <-c; math.IsNaN(x) || math.IsInf(x, 1); x = <-c {
   331  	}
   332  }
   333  
   334  func f64NaNOrNegInf(c <-chan float64) {
   335  	// This test assumes IsInf(x, -1) is implemented as x < -MaxFloat rather than x == Inf(-1).
   336  
   337  	// amd64:"JCS" -"JNE" -"JPS" -"JPC"
   338  	// riscv64:"FCLASSD" -"FLED" -"FLTD" -"FNED" -"FEQD"
   339  	for x := <-c; math.IsNaN(x) || math.IsInf(x, -1); x = <-c {
   340  	}
   341  }
   342  
   343  func f64NaNOrLtOne(c <-chan float64) {
   344  	// amd64:"JCS" -"JNE" -"JPS" -"JPC"
   345  	// riscv64:"FLED" -"FLTD" -"FNED" -"FEQD"
   346  	for x := <-c; math.IsNaN(x) || x < 1; x = <-c {
   347  	}
   348  }
   349  
   350  func f64NaNOrLteOne(c <-chan float64) {
   351  	// amd64:"JLS" -"JNE" -"JPS" -"JPC"
   352  	// riscv64:"FLTD" -"FLED" -"FNED" -"FEQD"
   353  	for x := <-c; x <= 1 || math.IsNaN(x); x = <-c {
   354  	}
   355  }
   356  
   357  func f64NaNOrGtOne(c <-chan float64) {
   358  	// amd64:"JCS" -"JNE" -"JPS" -"JPC"
   359  	// riscv64:"FLED" -"FLTD" -"FNED" -"FEQD"
   360  	for x := <-c; math.IsNaN(x) || x > 1; x = <-c {
   361  	}
   362  }
   363  
   364  func f64NaNOrGteOne(c <-chan float64) {
   365  	// amd64:"JLS" -"JNE" -"JPS" -"JPC"
   366  	// riscv64:"FLTD" -"FLED" -"FNED" -"FEQD"
   367  	for x := <-c; x >= 1 || math.IsNaN(x); x = <-c {
   368  	}
   369  }
   370  
   371  func f32NaNOrLtOne(c <-chan float32) {
   372  	// amd64:"JCS" -"JNE" -"JPS" -"JPC"
   373  	// riscv64:"FLES" -"FLTS" -"FNES" -"FEQS"
   374  	for x := <-c; x < 1 || x != x; x = <-c {
   375  	}
   376  }
   377  
   378  func f32NaNOrLteOne(c <-chan float32) {
   379  	// amd64:"JLS" -"JNE" -"JPS" -"JPC"
   380  	// riscv64:"FLTS" -"FLES" -"FNES" -"FEQS"
   381  	for x := <-c; x != x || x <= 1; x = <-c {
   382  	}
   383  }
   384  
   385  func f32NaNOrGtOne(c <-chan float32) {
   386  	// amd64:"JCS" -"JNE" -"JPS" -"JPC"
   387  	// riscv64:"FLES" -"FLTS" -"FNES" -"FEQS"
   388  	for x := <-c; x > 1 || x != x; x = <-c {
   389  	}
   390  }
   391  
   392  func f32NaNOrGteOne(c <-chan float32) {
   393  	// amd64:"JLS" -"JNE" -"JPS" -"JPC"
   394  	// riscv64:"FLTS" -"FLES" -"FNES" -"FEQS"
   395  	for x := <-c; x != x || x >= 1; x = <-c {
   396  	}
   397  }
   398  
   399  // ------------------------------------ //
   400  // regressions                          //
   401  // ------------------------------------ //
   402  
   403  func gte4(x uint64) bool {
   404  	return x >= 4
   405  }
   406  
   407  func lt20(x uint64) bool {
   408  	return x < 20
   409  }
   410  
   411  func issue74915(c <-chan uint64) {
   412  	// Check that the optimization is not blocked by function inlining.
   413  
   414  	// amd64:"CMPQ .+, [$]16" "ADDQ [$]-4,"
   415  	// s390x:"CLGIJ [$]4, R[0-9]+, [$]16" "ADD [$]-4,"
   416  	for x := <-c; gte4(x) && lt20(x); x = <-c {
   417  	}
   418  }
   419  

View as plain text