Initial commit: Go 1.23 release state
This commit is contained in:
144
test/codegen/stack.go
Normal file
144
test/codegen/stack.go
Normal file
@@ -0,0 +1,144 @@
|
||||
// asmcheck
|
||||
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package codegen
|
||||
|
||||
import "runtime"
|
||||
|
||||
// This file contains code generation tests related to the use of the
|
||||
// stack.
|
||||
|
||||
// Check that stack stores are optimized away.
|
||||
|
||||
// 386:"TEXT\t.*, [$]0-"
|
||||
// amd64:"TEXT\t.*, [$]0-"
|
||||
// arm:"TEXT\t.*, [$]-4-"
|
||||
// arm64:"TEXT\t.*, [$]0-"
|
||||
// mips:"TEXT\t.*, [$]-4-"
|
||||
// ppc64x:"TEXT\t.*, [$]0-"
|
||||
// s390x:"TEXT\t.*, [$]0-"
|
||||
func StackStore() int {
|
||||
var x int
|
||||
return *(&x)
|
||||
}
|
||||
|
||||
type T struct {
|
||||
A, B, C, D int // keep exported fields
|
||||
x, y, z int // reset unexported fields
|
||||
}
|
||||
|
||||
// Check that large structs are cleared directly (issue #24416).
|
||||
|
||||
// 386:"TEXT\t.*, [$]0-"
|
||||
// amd64:"TEXT\t.*, [$]0-"
|
||||
// arm:"TEXT\t.*, [$]0-" (spills return address)
|
||||
// arm64:"TEXT\t.*, [$]0-"
|
||||
// mips:"TEXT\t.*, [$]-4-"
|
||||
// ppc64x:"TEXT\t.*, [$]0-"
|
||||
// s390x:"TEXT\t.*, [$]0-"
|
||||
func ZeroLargeStruct(x *T) {
|
||||
t := T{}
|
||||
*x = t
|
||||
}
|
||||
|
||||
// Check that structs are partially initialised directly (issue #24386).
|
||||
|
||||
// Notes:
|
||||
// - 386 fails due to spilling a register
|
||||
// amd64:"TEXT\t.*, [$]0-"
|
||||
// arm:"TEXT\t.*, [$]0-" (spills return address)
|
||||
// arm64:"TEXT\t.*, [$]0-"
|
||||
// ppc64x:"TEXT\t.*, [$]0-"
|
||||
// s390x:"TEXT\t.*, [$]0-"
|
||||
// Note: that 386 currently has to spill a register.
|
||||
func KeepWanted(t *T) {
|
||||
*t = T{A: t.A, B: t.B, C: t.C, D: t.D}
|
||||
}
|
||||
|
||||
// Check that small array operations avoid using the stack (issue #15925).
|
||||
|
||||
// Notes:
|
||||
// - 386 fails due to spilling a register
|
||||
// - arm & mips fail due to softfloat calls
|
||||
// amd64:"TEXT\t.*, [$]0-"
|
||||
// arm64:"TEXT\t.*, [$]0-"
|
||||
// ppc64x:"TEXT\t.*, [$]0-"
|
||||
// s390x:"TEXT\t.*, [$]0-"
|
||||
func ArrayAdd64(a, b [4]float64) [4]float64 {
|
||||
return [4]float64{a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]}
|
||||
}
|
||||
|
||||
// Check that small array initialization avoids using the stack.
|
||||
|
||||
// 386:"TEXT\t.*, [$]0-"
|
||||
// amd64:"TEXT\t.*, [$]0-"
|
||||
// arm:"TEXT\t.*, [$]0-" (spills return address)
|
||||
// arm64:"TEXT\t.*, [$]0-"
|
||||
// mips:"TEXT\t.*, [$]-4-"
|
||||
// ppc64x:"TEXT\t.*, [$]0-"
|
||||
// s390x:"TEXT\t.*, [$]0-"
|
||||
func ArrayInit(i, j int) [4]int {
|
||||
return [4]int{i, 0, j, 0}
|
||||
}
|
||||
|
||||
// Check that assembly output has matching offset and base register
|
||||
// (issue #21064).
|
||||
|
||||
func check_asmout(b [2]int) int {
|
||||
runtime.GC() // use some frame
|
||||
// amd64:`.*b\+24\(SP\)`
|
||||
// arm:`.*b\+4\(FP\)`
|
||||
return b[1]
|
||||
}
|
||||
|
||||
// Check that simple functions get promoted to nosplit, even when
|
||||
// they might panic in various ways. See issue 31219.
|
||||
// amd64:"TEXT\t.*NOSPLIT.*"
|
||||
func MightPanic(a []int, i, j, k, s int) {
|
||||
_ = a[i] // panicIndex
|
||||
_ = a[i:j] // panicSlice
|
||||
_ = a[i:j:k] // also panicSlice
|
||||
_ = i << s // panicShift
|
||||
_ = i / j // panicDivide
|
||||
}
|
||||
|
||||
// Put a defer in a loop, so second defer is not open-coded
|
||||
func Defer() {
|
||||
for i := 0; i < 2; i++ {
|
||||
defer func() {}()
|
||||
}
|
||||
// amd64:`CALL\truntime\.deferprocStack`
|
||||
defer func() {}()
|
||||
}
|
||||
|
||||
// Check that stack slots are shared among values of the same
|
||||
// type, but not pointer-identical types. See issue 65783.
|
||||
|
||||
func spillSlotReuse() {
|
||||
// The return values of getp1 and getp2 need to be
|
||||
// spilled around the calls to nopInt. Make sure that
|
||||
// spill slot gets reused.
|
||||
|
||||
//arm64:`.*autotmp_2-8\(SP\)`
|
||||
getp1()[nopInt()] = 0
|
||||
//arm64:`.*autotmp_2-8\(SP\)`
|
||||
getp2()[nopInt()] = 0
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func nopInt() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func getp1() *[4]int {
|
||||
return nil
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func getp2() *[4]int {
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user