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  // Some of the clears get inlined, see #56997
    20  
    21  func SliceClear(s []int) []int {
    22  	// amd64:`.*memclrNoHeapPointers`
    23  	// ppc64x:`.*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  	// ppc64x:`.*memclrHasPointers`
    33  	for i := range s {
    34  		s[i] = nil
    35  	}
    36  	return s
    37  }
    38  
    39  // ------------------ //
    40  //      Extension     //
    41  // ------------------ //
    42  
    43  // Issue #21266 - avoid makeslice in append(x, make([]T, y)...)
    44  
    45  func SliceExtensionConst(s []int) []int {
    46  	// amd64:-`.*runtime\.memclrNoHeapPointers`
    47  	// amd64:-`.*runtime\.makeslice`
    48  	// amd64:-`.*runtime\.panicmakeslicelen`
    49  	// amd64:"MOVUPS\tX15"
    50  	// loong64:-`.*runtime\.memclrNoHeapPointers`
    51  	// ppc64x:-`.*runtime\.memclrNoHeapPointers`
    52  	// ppc64x:-`.*runtime\.makeslice`
    53  	// ppc64x:-`.*runtime\.panicmakeslicelen`
    54  	return append(s, make([]int, 1<<2)...)
    55  }
    56  
    57  func SliceExtensionConstInt64(s []int) []int {
    58  	// amd64:-`.*runtime\.memclrNoHeapPointers`
    59  	// amd64:-`.*runtime\.makeslice`
    60  	// amd64:-`.*runtime\.panicmakeslicelen`
    61  	// amd64:"MOVUPS\tX15"
    62  	// loong64:-`.*runtime\.memclrNoHeapPointers`
    63  	// ppc64x:-`.*runtime\.memclrNoHeapPointers`
    64  	// ppc64x:-`.*runtime\.makeslice`
    65  	// ppc64x:-`.*runtime\.panicmakeslicelen`
    66  	return append(s, make([]int, int64(1<<2))...)
    67  }
    68  
    69  func SliceExtensionConstUint64(s []int) []int {
    70  	// amd64:-`.*runtime\.memclrNoHeapPointers`
    71  	// amd64:-`.*runtime\.makeslice`
    72  	// amd64:-`.*runtime\.panicmakeslicelen`
    73  	// amd64:"MOVUPS\tX15"
    74  	// loong64:-`.*runtime\.memclrNoHeapPointers`
    75  	// ppc64x:-`.*runtime\.memclrNoHeapPointers`
    76  	// ppc64x:-`.*runtime\.makeslice`
    77  	// ppc64x:-`.*runtime\.panicmakeslicelen`
    78  	return append(s, make([]int, uint64(1<<2))...)
    79  }
    80  
    81  func SliceExtensionConstUint(s []int) []int {
    82  	// amd64:-`.*runtime\.memclrNoHeapPointers`
    83  	// amd64:-`.*runtime\.makeslice`
    84  	// amd64:-`.*runtime\.panicmakeslicelen`
    85  	// amd64:"MOVUPS\tX15"
    86  	// loong64:-`.*runtime\.memclrNoHeapPointers`
    87  	// ppc64x:-`.*runtime\.memclrNoHeapPointers`
    88  	// ppc64x:-`.*runtime\.makeslice`
    89  	// ppc64x:-`.*runtime\.panicmakeslicelen`
    90  	return append(s, make([]int, uint(1<<2))...)
    91  }
    92  
    93  // On ppc64x and loong64 continue to use memclrNoHeapPointers
    94  // for sizes >= 512.
    95  func SliceExtensionConst512(s []int) []int {
    96  	// amd64:-`.*runtime\.memclrNoHeapPointers`
    97  	// loong64:`.*runtime\.memclrNoHeapPointers`
    98  	// ppc64x:`.*runtime\.memclrNoHeapPointers`
    99  	return append(s, make([]int, 1<<9)...)
   100  }
   101  
   102  func SliceExtensionPointer(s []*int, l int) []*int {
   103  	// amd64:`.*runtime\.memclrHasPointers`
   104  	// amd64:-`.*runtime\.makeslice`
   105  	// ppc64x:`.*runtime\.memclrHasPointers`
   106  	// ppc64x:-`.*runtime\.makeslice`
   107  	return append(s, make([]*int, l)...)
   108  }
   109  
   110  func SliceExtensionVar(s []byte, l int) []byte {
   111  	// amd64:`.*runtime\.memclrNoHeapPointers`
   112  	// amd64:-`.*runtime\.makeslice`
   113  	// ppc64x:`.*runtime\.memclrNoHeapPointers`
   114  	// ppc64x:-`.*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  	// ppc64x:`.*runtime\.mallocgc`
   156  	// ppc64x:`.*runtime\.memmove`
   157  	// ppc64x:-`.*runtime\.makeslice`
   158  	a := make([]int, len(s))
   159  	copy(a, s)
   160  	return a
   161  }
   162  
   163  func SliceMakeCopyLenPtr(s []*int) []*int {
   164  	// amd64:`.*runtime\.makeslicecopy`
   165  	// amd64:-`.*runtime\.makeslice\(`
   166  	// amd64:-`.*runtime\.typedslicecopy
   167  	// ppc64x:`.*runtime\.makeslicecopy`
   168  	// ppc64x:-`.*runtime\.makeslice\(`
   169  	// ppc64x:-`.*runtime\.typedslicecopy
   170  	a := make([]*int, len(s))
   171  	copy(a, s)
   172  	return a
   173  }
   174  
   175  func SliceMakeCopyConst(s []int) []int {
   176  	// amd64:`.*runtime\.makeslicecopy`
   177  	// amd64:-`.*runtime\.makeslice\(`
   178  	// amd64:-`.*runtime\.memmove`
   179  	a := make([]int, 4)
   180  	copy(a, s)
   181  	return a
   182  }
   183  
   184  func SliceMakeCopyConstPtr(s []*int) []*int {
   185  	// amd64:`.*runtime\.makeslicecopy`
   186  	// amd64:-`.*runtime\.makeslice\(`
   187  	// amd64:-`.*runtime\.typedslicecopy
   188  	a := make([]*int, 4)
   189  	copy(a, s)
   190  	return a
   191  }
   192  
   193  func SliceMakeCopyNoOptNoDeref(s []*int) []*int {
   194  	a := new([]*int)
   195  	// amd64:-`.*runtime\.makeslicecopy`
   196  	// amd64:`.*runtime\.makeslice\(`
   197  	*a = make([]*int, 4)
   198  	// amd64:-`.*runtime\.makeslicecopy`
   199  	// amd64:`.*runtime\.typedslicecopy`
   200  	copy(*a, s)
   201  	return *a
   202  }
   203  
   204  func SliceMakeCopyNoOptNoVar(s []*int) []*int {
   205  	a := make([][]*int, 1)
   206  	// amd64:-`.*runtime\.makeslicecopy`
   207  	// amd64:`.*runtime\.makeslice\(`
   208  	a[0] = make([]*int, 4)
   209  	// amd64:-`.*runtime\.makeslicecopy`
   210  	// amd64:`.*runtime\.typedslicecopy`
   211  	copy(a[0], s)
   212  	return a[0]
   213  }
   214  
   215  func SliceMakeCopyNoOptBlank(s []*int) []*int {
   216  	var a []*int
   217  	// amd64:-`.*runtime\.makeslicecopy`
   218  	_ = make([]*int, 4)
   219  	// amd64:-`.*runtime\.makeslicecopy`
   220  	// amd64:`.*runtime\.typedslicecopy`
   221  	copy(a, s)
   222  	return a
   223  }
   224  
   225  func SliceMakeCopyNoOptNoMake(s []*int) []*int {
   226  	// amd64:-`.*runtime\.makeslicecopy`
   227  	// amd64:-`.*runtime\.objectnew`
   228  	a := *new([]*int)
   229  	// amd64:-`.*runtime\.makeslicecopy`
   230  	// amd64:`.*runtime\.typedslicecopy`
   231  	copy(a, s)
   232  	return a
   233  }
   234  
   235  func SliceMakeCopyNoOptNoHeapAlloc(s []*int) int {
   236  	// amd64:-`.*runtime\.makeslicecopy`
   237  	a := make([]*int, 4)
   238  	// amd64:-`.*runtime\.makeslicecopy`
   239  	// amd64:`.*runtime\.typedslicecopy`
   240  	copy(a, s)
   241  	return cap(a)
   242  }
   243  
   244  func SliceMakeCopyNoOptNoCap(s []*int) []*int {
   245  	// amd64:-`.*runtime\.makeslicecopy`
   246  	// amd64:`.*runtime\.makeslice\(`
   247  	a := make([]*int, 0, 4)
   248  	// amd64:-`.*runtime\.makeslicecopy`
   249  	// amd64:`.*runtime\.typedslicecopy`
   250  	copy(a, s)
   251  	return a
   252  }
   253  
   254  func SliceMakeCopyNoOptNoCopy(s []*int) []*int {
   255  	copy := func(x, y []*int) {}
   256  	// amd64:-`.*runtime\.makeslicecopy`
   257  	// amd64:`.*runtime\.makeslice\(`
   258  	a := make([]*int, 4)
   259  	// amd64:-`.*runtime\.makeslicecopy`
   260  	copy(a, s)
   261  	return a
   262  }
   263  
   264  func SliceMakeCopyNoOptWrongOrder(s []*int) []*int {
   265  	// amd64:-`.*runtime\.makeslicecopy`
   266  	// amd64:`.*runtime\.makeslice\(`
   267  	a := make([]*int, 4)
   268  	// amd64:`.*runtime\.typedslicecopy`
   269  	// amd64:-`.*runtime\.makeslicecopy`
   270  	copy(s, a)
   271  	return a
   272  }
   273  
   274  func SliceMakeCopyNoOptWrongAssign(s []*int) []*int {
   275  	var a []*int
   276  	// amd64:-`.*runtime\.makeslicecopy`
   277  	// amd64:`.*runtime\.makeslice\(`
   278  	s = make([]*int, 4)
   279  	// amd64:`.*runtime\.typedslicecopy`
   280  	// amd64:-`.*runtime\.makeslicecopy`
   281  	copy(a, s)
   282  	return s
   283  }
   284  
   285  func SliceMakeCopyNoOptCopyLength(s []*int) (int, []*int) {
   286  	// amd64:-`.*runtime\.makeslicecopy`
   287  	// amd64:`.*runtime\.makeslice\(`
   288  	a := make([]*int, 4)
   289  	// amd64:`.*runtime\.typedslicecopy`
   290  	// amd64:-`.*runtime\.makeslicecopy`
   291  	n := copy(a, s)
   292  	return n, a
   293  }
   294  
   295  func SliceMakeCopyNoOptSelfCopy(s []*int) []*int {
   296  	// amd64:-`.*runtime\.makeslicecopy`
   297  	// amd64:`.*runtime\.makeslice\(`
   298  	a := make([]*int, 4)
   299  	// amd64:`.*runtime\.typedslicecopy`
   300  	// amd64:-`.*runtime\.makeslicecopy`
   301  	copy(a, a)
   302  	return a
   303  }
   304  
   305  func SliceMakeCopyNoOptTargetReference(s []*int) []*int {
   306  	// amd64:-`.*runtime\.makeslicecopy`
   307  	// amd64:`.*runtime\.makeslice\(`
   308  	a := make([]*int, 4)
   309  	// amd64:`.*runtime\.typedslicecopy`
   310  	// amd64:-`.*runtime\.makeslicecopy`
   311  	copy(a, s[:len(a)])
   312  	return a
   313  }
   314  
   315  func SliceMakeCopyNoOptCap(s []int) []int {
   316  	// amd64:-`.*runtime\.makeslicecopy`
   317  	// amd64:`.*runtime\.makeslice\(`
   318  	a := make([]int, len(s), 9)
   319  	// amd64:-`.*runtime\.makeslicecopy`
   320  	// amd64:`.*runtime\.memmove`
   321  	copy(a, s)
   322  	return a
   323  }
   324  
   325  func SliceMakeCopyNoMemmoveDifferentLen(s []int) []int {
   326  	// amd64:`.*runtime\.makeslicecopy`
   327  	// amd64:-`.*runtime\.memmove`
   328  	a := make([]int, len(s)-1)
   329  	// amd64:-`.*runtime\.memmove`
   330  	copy(a, s)
   331  	return a
   332  }
   333  
   334  func SliceMakeEmptyPointerToZerobase() []int {
   335  	// amd64:`LEAQ.+runtime\.zerobase`
   336  	// amd64:-`.*runtime\.makeslice`
   337  	return make([]int, 0)
   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  		// ppc64x:-"NEG"
   410  		return c[b:]
   411  	}
   412  	return a
   413  }
   414  
   415  func SliceWithSubtractBound(a []int, b int) []int {
   416  	// ppc64x:"SUBC",-"NEG"
   417  	return a[(3 - b):]
   418  }
   419  
   420  // --------------------------------------- //
   421  //   Code generation for unsafe.Slice      //
   422  // --------------------------------------- //
   423  
   424  func Slice1(p *byte, i int) []byte {
   425  	// amd64:-"MULQ"
   426  	return unsafe.Slice(p, i)
   427  }
   428  func Slice0(p *struct{}, i int) []struct{} {
   429  	// amd64:-"MULQ"
   430  	return unsafe.Slice(p, i)
   431  }
   432  

View as plain text