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

View as plain text