Source file test/codegen/slices.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 handling of
    12  // slice types.
    13  
    14  // ------------------ //
    15  //      Clear         //
    16  // ------------------ //
    17  
    18  // Issue #5373 optimize memset idiom
    19  
    20  func SliceClear(s []int) []int {
    21  	// amd64:`.*memclrNoHeapPointers`
    22  	// ppc64le:`.*memclrNoHeapPointers`
    23  	// ppc64:`.*memclrNoHeapPointers`
    24  	for i := range s {
    25  		s[i] = 0
    26  	}
    27  	return s
    28  }
    29  
    30  func SliceClearPointers(s []*int) []*int {
    31  	// amd64:`.*memclrHasPointers`
    32  	// ppc64le:`.*memclrHasPointers`
    33  	// ppc64:`.*memclrHasPointers`
    34  	for i := range s {
    35  		s[i] = nil
    36  	}
    37  	return s
    38  }
    39  
    40  // ------------------ //
    41  //      Extension     //
    42  // ------------------ //
    43  
    44  // Issue #21266 - avoid makeslice in append(x, make([]T, y)...)
    45  
    46  func SliceExtensionConst(s []int) []int {
    47  	// amd64:`.*runtime\.memclrNoHeapPointers`
    48  	// amd64:-`.*runtime\.makeslice`
    49  	// amd64:-`.*runtime\.panicmakeslicelen`
    50  	// ppc64le:`.*runtime\.memclrNoHeapPointers`
    51  	// ppc64le:-`.*runtime\.makeslice`
    52  	// ppc64le:-`.*runtime\.panicmakeslicelen`
    53  	// ppc64:`.*runtime\.memclrNoHeapPointers`
    54  	// ppc64:-`.*runtime\.makeslice`
    55  	// ppc64:-`.*runtime\.panicmakeslicelen`
    56  	return append(s, make([]int, 1<<2)...)
    57  }
    58  
    59  func SliceExtensionConstInt64(s []int) []int {
    60  	// amd64:`.*runtime\.memclrNoHeapPointers`
    61  	// amd64:-`.*runtime\.makeslice`
    62  	// amd64:-`.*runtime\.panicmakeslicelen`
    63  	// ppc64le:`.*runtime\.memclrNoHeapPointers`
    64  	// ppc64le:-`.*runtime\.makeslice`
    65  	// ppc64le:-`.*runtime\.panicmakeslicelen`
    66  	// ppc64:`.*runtime\.memclrNoHeapPointers`
    67  	// ppc64:-`.*runtime\.makeslice`
    68  	// ppc64:-`.*runtime\.panicmakeslicelen`
    69  	return append(s, make([]int, int64(1<<2))...)
    70  }
    71  
    72  func SliceExtensionConstUint64(s []int) []int {
    73  	// amd64:`.*runtime\.memclrNoHeapPointers`
    74  	// amd64:-`.*runtime\.makeslice`
    75  	// amd64:-`.*runtime\.panicmakeslicelen`
    76  	// ppc64le:`.*runtime\.memclrNoHeapPointers`
    77  	// ppc64le:-`.*runtime\.makeslice`
    78  	// ppc64le:-`.*runtime\.panicmakeslicelen`
    79  	// ppc64:`.*runtime\.memclrNoHeapPointers`
    80  	// ppc64:-`.*runtime\.makeslice`
    81  	// ppc64:-`.*runtime\.panicmakeslicelen`
    82  	return append(s, make([]int, uint64(1<<2))...)
    83  }
    84  
    85  func SliceExtensionConstUint(s []int) []int {
    86  	// amd64:`.*runtime\.memclrNoHeapPointers`
    87  	// amd64:-`.*runtime\.makeslice`
    88  	// amd64:-`.*runtime\.panicmakeslicelen`
    89  	// ppc64le:`.*runtime\.memclrNoHeapPointers`
    90  	// ppc64le:-`.*runtime\.makeslice`
    91  	// ppc64le:-`.*runtime\.panicmakeslicelen`
    92  	// ppc64:`.*runtime\.memclrNoHeapPointers`
    93  	// ppc64:-`.*runtime\.makeslice`
    94  	// ppc64:-`.*runtime\.panicmakeslicelen`
    95  	return append(s, make([]int, uint(1<<2))...)
    96  }
    97  
    98  func SliceExtensionPointer(s []*int, l int) []*int {
    99  	// amd64:`.*runtime\.memclrHasPointers`
   100  	// amd64:-`.*runtime\.makeslice`
   101  	// ppc64le:`.*runtime\.memclrHasPointers`
   102  	// ppc64le:-`.*runtime\.makeslice`
   103  	// ppc64:`.*runtime\.memclrHasPointers`
   104  	// ppc64:-`.*runtime\.makeslice`
   105  	return append(s, make([]*int, l)...)
   106  }
   107  
   108  func SliceExtensionVar(s []byte, l int) []byte {
   109  	// amd64:`.*runtime\.memclrNoHeapPointers`
   110  	// amd64:-`.*runtime\.makeslice`
   111  	// ppc64le:`.*runtime\.memclrNoHeapPointers`
   112  	// ppc64le:-`.*runtime\.makeslice`
   113  	// ppc64:`.*runtime\.memclrNoHeapPointers`
   114  	// ppc64:-`.*runtime\.makeslice`
   115  	return append(s, make([]byte, l)...)
   116  }
   117  
   118  func SliceExtensionVarInt64(s []byte, l int64) []byte {
   119  	// amd64:`.*runtime\.memclrNoHeapPointers`
   120  	// amd64:-`.*runtime\.makeslice`
   121  	// amd64:`.*runtime\.panicmakeslicelen`
   122  	return append(s, make([]byte, l)...)
   123  }
   124  
   125  func SliceExtensionVarUint64(s []byte, l uint64) []byte {
   126  	// amd64:`.*runtime\.memclrNoHeapPointers`
   127  	// amd64:-`.*runtime\.makeslice`
   128  	// amd64:`.*runtime\.panicmakeslicelen`
   129  	return append(s, make([]byte, l)...)
   130  }
   131  
   132  func SliceExtensionVarUint(s []byte, l uint) []byte {
   133  	// amd64:`.*runtime\.memclrNoHeapPointers`
   134  	// amd64:-`.*runtime\.makeslice`
   135  	// amd64:`.*runtime\.panicmakeslicelen`
   136  	return append(s, make([]byte, l)...)
   137  }
   138  
   139  func SliceExtensionInt64(s []int, l64 int64) []int {
   140  	// 386:`.*runtime\.makeslice`
   141  	// 386:-`.*runtime\.memclr`
   142  	return append(s, make([]int, l64)...)
   143  }
   144  
   145  // ------------------ //
   146  //      Make+Copy     //
   147  // ------------------ //
   148  
   149  // Issue #26252 - avoid memclr for make+copy
   150  
   151  func SliceMakeCopyLen(s []int) []int {
   152  	// amd64:`.*runtime\.mallocgc`
   153  	// amd64:`.*runtime\.memmove`
   154  	// amd64:-`.*runtime\.makeslice`
   155  	// ppc64le:`.*runtime\.mallocgc`
   156  	// ppc64le:`.*runtime\.memmove`
   157  	// ppc64le:-`.*runtime\.makeslice`
   158  	// ppc64:`.*runtime\.mallocgc`
   159  	// ppc64:`.*runtime\.memmove`
   160  	// ppc64:-`.*runtime\.makeslice`
   161  	a := make([]int, len(s))
   162  	copy(a, s)
   163  	return a
   164  }
   165  
   166  func SliceMakeCopyLenPtr(s []*int) []*int {
   167  	// amd64:`.*runtime\.makeslicecopy`
   168  	// amd64:-`.*runtime\.makeslice\(`
   169  	// amd64:-`.*runtime\.typedslicecopy
   170  	// ppc64le:`.*runtime\.makeslicecopy`
   171  	// ppc64le:-`.*runtime\.makeslice\(`
   172  	// ppc64le:-`.*runtime\.typedslicecopy
   173  	// ppc64:`.*runtime\.makeslicecopy`
   174  	// ppc64:-`.*runtime\.makeslice\(`
   175  	// ppc64:-`.*runtime\.typedslicecopy
   176  	a := make([]*int, len(s))
   177  	copy(a, s)
   178  	return a
   179  }
   180  
   181  func SliceMakeCopyConst(s []int) []int {
   182  	// amd64:`.*runtime\.makeslicecopy`
   183  	// amd64:-`.*runtime\.makeslice\(`
   184  	// amd64:-`.*runtime\.memmove`
   185  	a := make([]int, 4)
   186  	copy(a, s)
   187  	return a
   188  }
   189  
   190  func SliceMakeCopyConstPtr(s []*int) []*int {
   191  	// amd64:`.*runtime\.makeslicecopy`
   192  	// amd64:-`.*runtime\.makeslice\(`
   193  	// amd64:-`.*runtime\.typedslicecopy
   194  	a := make([]*int, 4)
   195  	copy(a, s)
   196  	return a
   197  }
   198  
   199  func SliceMakeCopyNoOptNoDeref(s []*int) []*int {
   200  	a := new([]*int)
   201  	// amd64:-`.*runtime\.makeslicecopy`
   202  	// amd64:`.*runtime\.makeslice\(`
   203  	*a = make([]*int, 4)
   204  	// amd64:-`.*runtime\.makeslicecopy`
   205  	// amd64:`.*runtime\.typedslicecopy`
   206  	copy(*a, s)
   207  	return *a
   208  }
   209  
   210  func SliceMakeCopyNoOptNoVar(s []*int) []*int {
   211  	a := make([][]*int, 1)
   212  	// amd64:-`.*runtime\.makeslicecopy`
   213  	// amd64:`.*runtime\.makeslice\(`
   214  	a[0] = make([]*int, 4)
   215  	// amd64:-`.*runtime\.makeslicecopy`
   216  	// amd64:`.*runtime\.typedslicecopy`
   217  	copy(a[0], s)
   218  	return a[0]
   219  }
   220  
   221  func SliceMakeCopyNoOptBlank(s []*int) []*int {
   222  	var a []*int
   223  	// amd64:-`.*runtime\.makeslicecopy`
   224  	_ = make([]*int, 4)
   225  	// amd64:-`.*runtime\.makeslicecopy`
   226  	// amd64:`.*runtime\.typedslicecopy`
   227  	copy(a, s)
   228  	return a
   229  }
   230  
   231  func SliceMakeCopyNoOptNoMake(s []*int) []*int {
   232  	// amd64:-`.*runtime\.makeslicecopy`
   233  	// amd64:-`.*runtime\.objectnew`
   234  	a := *new([]*int)
   235  	// amd64:-`.*runtime\.makeslicecopy`
   236  	// amd64:`.*runtime\.typedslicecopy`
   237  	copy(a, s)
   238  	return a
   239  }
   240  
   241  func SliceMakeCopyNoOptNoHeapAlloc(s []*int) int {
   242  	// amd64:-`.*runtime\.makeslicecopy`
   243  	a := make([]*int, 4)
   244  	// amd64:-`.*runtime\.makeslicecopy`
   245  	// amd64:`.*runtime\.typedslicecopy`
   246  	copy(a, s)
   247  	return cap(a)
   248  }
   249  
   250  func SliceMakeCopyNoOptNoCap(s []*int) []*int {
   251  	// amd64:-`.*runtime\.makeslicecopy`
   252  	// amd64:`.*runtime\.makeslice\(`
   253  	a := make([]*int, 0, 4)
   254  	// amd64:-`.*runtime\.makeslicecopy`
   255  	// amd64:`.*runtime\.typedslicecopy`
   256  	copy(a, s)
   257  	return a
   258  }
   259  
   260  func SliceMakeCopyNoOptNoCopy(s []*int) []*int {
   261  	copy := func(x, y []*int) {}
   262  	// amd64:-`.*runtime\.makeslicecopy`
   263  	// amd64:`.*runtime\.makeslice\(`
   264  	a := make([]*int, 4)
   265  	// amd64:-`.*runtime\.makeslicecopy`
   266  	copy(a, s)
   267  	return a
   268  }
   269  
   270  func SliceMakeCopyNoOptWrongOrder(s []*int) []*int {
   271  	// amd64:-`.*runtime\.makeslicecopy`
   272  	// amd64:`.*runtime\.makeslice\(`
   273  	a := make([]*int, 4)
   274  	// amd64:`.*runtime\.typedslicecopy`
   275  	// amd64:-`.*runtime\.makeslicecopy`
   276  	copy(s, a)
   277  	return a
   278  }
   279  
   280  func SliceMakeCopyNoOptWrongAssign(s []*int) []*int {
   281  	var a []*int
   282  	// amd64:-`.*runtime\.makeslicecopy`
   283  	// amd64:`.*runtime\.makeslice\(`
   284  	s = make([]*int, 4)
   285  	// amd64:`.*runtime\.typedslicecopy`
   286  	// amd64:-`.*runtime\.makeslicecopy`
   287  	copy(a, s)
   288  	return s
   289  }
   290  
   291  func SliceMakeCopyNoOptCopyLength(s []*int) (int, []*int) {
   292  	// amd64:-`.*runtime\.makeslicecopy`
   293  	// amd64:`.*runtime\.makeslice\(`
   294  	a := make([]*int, 4)
   295  	// amd64:`.*runtime\.typedslicecopy`
   296  	// amd64:-`.*runtime\.makeslicecopy`
   297  	n := copy(a, s)
   298  	return n, a
   299  }
   300  
   301  func SliceMakeCopyNoOptSelfCopy(s []*int) []*int {
   302  	// amd64:-`.*runtime\.makeslicecopy`
   303  	// amd64:`.*runtime\.makeslice\(`
   304  	a := make([]*int, 4)
   305  	// amd64:`.*runtime\.typedslicecopy`
   306  	// amd64:-`.*runtime\.makeslicecopy`
   307  	copy(a, a)
   308  	return a
   309  }
   310  
   311  func SliceMakeCopyNoOptTargetReference(s []*int) []*int {
   312  	// amd64:-`.*runtime\.makeslicecopy`
   313  	// amd64:`.*runtime\.makeslice\(`
   314  	a := make([]*int, 4)
   315  	// amd64:`.*runtime\.typedslicecopy`
   316  	// amd64:-`.*runtime\.makeslicecopy`
   317  	copy(a, s[:len(a)])
   318  	return a
   319  }
   320  
   321  func SliceMakeCopyNoOptCap(s []int) []int {
   322  	// amd64:-`.*runtime\.makeslicecopy`
   323  	// amd64:`.*runtime\.makeslice\(`
   324  	a := make([]int, len(s), 9)
   325  	// amd64:-`.*runtime\.makeslicecopy`
   326  	// amd64:`.*runtime\.memmove`
   327  	copy(a, s)
   328  	return a
   329  }
   330  
   331  func SliceMakeCopyNoMemmoveDifferentLen(s []int) []int {
   332  	// amd64:`.*runtime\.makeslicecopy`
   333  	// amd64:-`.*runtime\.memmove`
   334  	a := make([]int, len(s)-1)
   335  	// amd64:-`.*runtime\.memmove`
   336  	copy(a, s)
   337  	return a
   338  }
   339  
   340  // ---------------------- //
   341  //   Nil check of &s[0]   //
   342  // ---------------------- //
   343  // See issue 30366
   344  func SliceNilCheck(s []int) {
   345  	p := &s[0]
   346  	// amd64:-`TESTB`
   347  	_ = *p
   348  }
   349  
   350  // ---------------------- //
   351  //   Init slice literal   //
   352  // ---------------------- //
   353  // See issue 21561
   354  func InitSmallSliceLiteral() []int {
   355  	// amd64:`MOVQ\t[$]42`
   356  	return []int{42}
   357  }
   358  
   359  func InitNotSmallSliceLiteral() []int {
   360  	// amd64:`LEAQ\t.*stmp_`
   361  	return []int{
   362  		42,
   363  		42,
   364  		42,
   365  		42,
   366  		42,
   367  		42,
   368  		42,
   369  		42,
   370  		42,
   371  		42,
   372  		42,
   373  		42,
   374  		42,
   375  		42,
   376  		42,
   377  		42,
   378  		42,
   379  		42,
   380  		42,
   381  		42,
   382  		42,
   383  		42,
   384  		42,
   385  		42,
   386  		42,
   387  		42,
   388  		42,
   389  		42,
   390  		42,
   391  		42,
   392  		42,
   393  		42,
   394  		42,
   395  		42,
   396  		42,
   397  		42,
   398  	}
   399  }
   400  
   401  // --------------------------------------- //
   402  //   Test PPC64 SUBFCconst folding rules   //
   403  //   triggered by slice operations.        //
   404  // --------------------------------------- //
   405  
   406  func SliceWithConstCompare(a []int, b int) []int {
   407  	var c []int = []int{1, 2, 3, 4, 5}
   408  	if b+len(a) < len(c) {
   409  		// ppc64le:-"NEG"
   410  		// ppc64:-"NEG"
   411  		return c[b:]
   412  	}
   413  	return a
   414  }
   415  
   416  func SliceWithSubtractBound(a []int, b int) []int {
   417  	// ppc64le:"SUBC",-"NEG"
   418  	// ppc64:"SUBC",-"NEG"
   419  	return a[(3 - b):]
   420  }
   421  
   422  // --------------------------------------- //
   423  //   Code generation for unsafe.Slice      //
   424  // --------------------------------------- //
   425  
   426  func Slice1(p *byte, i int) []byte {
   427  	// amd64:-"MULQ"
   428  	return unsafe.Slice(p, i)
   429  }
   430  func Slice0(p *struct{}, i int) []struct{} {
   431  	// amd64:-"MULQ"
   432  	return unsafe.Slice(p, i)
   433  }
   434  

View as plain text