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