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 7package codegen 8 9import "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 21func 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 30func 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 45func 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 56func 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 67func 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 78func 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. 91func SliceExtensionConst512(s []int) []int { 92 // amd64:-`.*runtime\.memclrNoHeapPointers` 93 // ppc64x:`.*runtime\.memclrNoHeapPointers` 94 return append(s, make([]int, 1<<9)...) 95} 96 97func 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 105func 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 113func 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 120func 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 127func 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 134func 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 146func 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 158func 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 170func 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 179func 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 188func 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 199func 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 210func 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 220func 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 230func 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 239func 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 249func 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 259func 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 269func 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 280func 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 290func 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 300func 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 310func 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 320func 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 329func 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 339func SliceNilCheck(s []int) { 340 p := &s[0] 341 // amd64:-`TESTB` 342 _ = *p 343} 344 345// ---------------------- // 346// Init slice literal // 347// ---------------------- // 348// See issue 21561 349func InitSmallSliceLiteral() []int { 350 // amd64:`MOVQ\t[$]42` 351 return []int{42} 352} 353 354func 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 401func 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 410func 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 419func Slice1(p *byte, i int) []byte { 420 // amd64:-"MULQ" 421 return unsafe.Slice(p, i) 422} 423func Slice0(p *struct{}, i int) []struct{} { 424 // amd64:-"MULQ" 425 return unsafe.Slice(p, i) 426} 427