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