Update to go1.24.0

This commit is contained in:
Vorapol Rinsatitnon
2025-02-14 12:42:07 +07:00
parent 25e497e367
commit bf266cebe6
3169 changed files with 236789 additions and 60275 deletions

View File

@@ -629,3 +629,39 @@ func constantFold3(i, j int) int {
r := (5 * i) * (6 * j)
return r
}
// ----------------- //
// Integer Min/Max //
// ----------------- //
func Int64Min(a, b int64) int64 {
// amd64: "CMPQ","CMOVQLT"
// arm64: "CMP","CSEL"
// riscv64/rva20u64:"BLT\t"
// riscv64/rva22u64:"MIN\t"
return min(a, b)
}
func Int64Max(a, b int64) int64 {
// amd64: "CMPQ","CMOVQGT"
// arm64: "CMP","CSEL"
// riscv64/rva20u64:"BLT\t"
// riscv64/rva22u64:"MAX\t"
return max(a, b)
}
func Uint64Min(a, b uint64) uint64 {
// amd64: "CMPQ","CMOVQCS"
// arm64: "CMP","CSEL"
// riscv64/rva20u64:"BLTU"
// riscv64/rva22u64:"MINU"
return min(a, b)
}
func Uint64Max(a, b uint64) uint64 {
// amd64: "CMPQ","CMOVQHI"
// arm64: "CMP","CSEL"
// riscv64/rva20u64:"BLTU"
// riscv64/rva22u64:"MAXU"
return max(a, b)
}

View File

@@ -22,6 +22,74 @@ func (c *Counter) Increment() {
// arm64/v8.1:"LDADDALW"
// arm64/v8.0:".*arm64HasATOMICS"
// arm64/v8.1:-".*arm64HasATOMICS"
// amd64:"LOCK",-"CMPXCHG"
atomic.AddInt32(&c.count, 1)
}
func atomicLogical64(x *atomic.Uint64) uint64 {
var r uint64
// arm64/v8.0:"LDCLRALD"
// arm64/v8.1:"LDCLRALD"
// arm64/v8.0:".*arm64HasATOMICS"
// arm64/v8.1:-".*arm64HasATOMICS"
// On amd64, make sure we use LOCK+AND instead of CMPXCHG when we don't use the result.
// amd64:"LOCK",-"CMPXCHGQ"
x.And(11)
// arm64/v8.0:"LDCLRALD"
// arm64/v8.1:"LDCLRALD"
// arm64/v8.0:".*arm64HasATOMICS"
// arm64/v8.1:-".*arm64HasATOMICS"
// amd64:"LOCK","CMPXCHGQ"
r += x.And(22)
// arm64/v8.0:"LDORALD"
// arm64/v8.1:"LDORALD"
// arm64/v8.0:".*arm64HasATOMICS"
// arm64/v8.1:-".*arm64HasATOMICS"
// On amd64, make sure we use LOCK+OR instead of CMPXCHG when we don't use the result.
// amd64:"LOCK",-"CMPXCHGQ"
x.Or(33)
// arm64/v8.0:"LDORALD"
// arm64/v8.1:"LDORALD"
// arm64/v8.0:".*arm64HasATOMICS"
// arm64/v8.1:-".*arm64HasATOMICS"
// amd64:"LOCK","CMPXCHGQ"
r += x.Or(44)
return r
}
func atomicLogical32(x *atomic.Uint32) uint32 {
var r uint32
// arm64/v8.0:"LDCLRALW"
// arm64/v8.1:"LDCLRALW"
// arm64/v8.0:".*arm64HasATOMICS"
// arm64/v8.1:-".*arm64HasATOMICS"
// On amd64, make sure we use LOCK+AND instead of CMPXCHG when we don't use the result.
// amd64:"LOCK",-"CMPXCHGL"
x.And(11)
// arm64/v8.0:"LDCLRALW"
// arm64/v8.1:"LDCLRALW"
// arm64/v8.0:".*arm64HasATOMICS"
// arm64/v8.1:-".*arm64HasATOMICS"
// amd64:"LOCK","CMPXCHGL"
r += x.And(22)
// arm64/v8.0:"LDORALW"
// arm64/v8.1:"LDORALW"
// arm64/v8.0:".*arm64HasATOMICS"
// arm64/v8.1:-".*arm64HasATOMICS"
// On amd64, make sure we use LOCK+OR instead of CMPXCHG when we don't use the result.
// amd64:"LOCK",-"CMPXCHGL"
x.Or(33)
// arm64/v8.0:"LDORALW"
// arm64/v8.1:"LDORALW"
// arm64/v8.0:".*arm64HasATOMICS"
// arm64/v8.1:-".*arm64HasATOMICS"
// amd64:"LOCK","CMPXCHGL"
r += x.Or(44)
return r
}

View File

@@ -358,11 +358,15 @@ func rev16w(c uint32) (uint32, uint32, uint32) {
func shift(x uint32, y uint16, z uint8) uint64 {
// arm64:-`MOVWU`,-`LSR\t[$]32`
// loong64:-`MOVWU`,-`SRLV\t[$]32`
a := uint64(x) >> 32
// arm64:-`MOVHU
// loong64:-`MOVHU`,-`SRLV\t[$]16`
b := uint64(y) >> 16
// arm64:-`MOVBU`
// loong64:-`MOVBU`,-`SRLV\t[$]8`
c := uint64(z) >> 8
// arm64:`MOVD\tZR`,-`ADD\tR[0-9]+>>16`,-`ADD\tR[0-9]+>>8`,
// loong64:`MOVV\t[$]0`,-`ADDVU`
return a + b + c
}

View File

@@ -366,6 +366,7 @@ func issue48467(x, y uint64) uint64 {
func foldConst(x, y uint64) uint64 {
// arm64: "ADDS\t[$]7",-"MOVD\t[$]7"
// ppc64x: "ADDC\t[$]7,"
d, b := bits.Add64(x, 7, 0)
return b & d
}

View File

@@ -217,53 +217,53 @@ func TestSetInvGeFp64(x float64, y float64) bool {
}
func TestLogicalCompareZero(x *[64]uint64) {
// ppc64x:"ANDCC",^"AND"
b := x[0]&3
if b!=0 {
b := x[0] & 3
if b != 0 {
x[0] = b
}
// ppc64x:"ANDCC",^"AND"
b = x[1]&x[2]
if b!=0 {
b = x[1] & x[2]
if b != 0 {
x[1] = b
}
// ppc64x:"ANDNCC",^"ANDN"
b = x[1]&^x[2]
if b!=0 {
b = x[1] &^ x[2]
if b != 0 {
x[1] = b
}
// ppc64x:"ORCC",^"OR"
b = x[3]|x[4]
if b!=0 {
b = x[3] | x[4]
if b != 0 {
x[3] = b
}
// ppc64x:"SUBCC",^"SUB"
b = x[5]-x[6]
if b!=0 {
b = x[5] - x[6]
if b != 0 {
x[5] = b
}
// ppc64x:"NORCC",^"NOR"
b = ^(x[5]|x[6])
if b!=0 {
b = ^(x[5] | x[6])
if b != 0 {
x[5] = b
}
// ppc64x:"XORCC",^"XOR"
b = x[7]^x[8]
if b!=0 {
b = x[7] ^ x[8]
if b != 0 {
x[7] = b
}
// ppc64x:"ADDCC",^"ADD"
b = x[9]+x[10]
if b!=0 {
b = x[9] + x[10]
if b != 0 {
x[9] = b
}
// ppc64x:"NEGCC",^"NEG"
b = -x[11]
if b!=0 {
if b != 0 {
x[11] = b
}
// ppc64x:"CNTLZDCC",^"CNTLZD"
b = uint64(bits.LeadingZeros64(x[12]))
if b!=0 {
if b != 0 {
x[12] = b
}
@@ -273,4 +273,17 @@ func TestLogicalCompareZero(x *[64]uint64) {
x[12] = uint64(c)
}
// ppc64x:"MULHDUCC",^"MULHDU"
hi, _ := bits.Mul64(x[13], x[14])
if hi != 0 {
x[14] = hi
}
}
func constantWrite(b bool, p *bool) {
if b {
// amd64:`MOVB\t[$]1, \(`
*p = b
}
}

View File

@@ -233,9 +233,9 @@ func CmpToZero(a, b, d int32, e, f int64, deOptC0, deOptC1 bool) int32 {
// arm:`AND`,-`TST`
// 386:`ANDL`
c6 := a&d >= 0
// arm64:`TST\sR[0-9]+<<3,\sR[0-9]+`
// For arm64, could be TST+BGE or AND+TBZ
c7 := e&(f<<3) < 0
// arm64:`CMN\sR[0-9]+<<3,\sR[0-9]+`
// For arm64, could be CMN+BPL or ADD+TBZ
c8 := e+(f<<3) < 0
// arm64:`TST\sR[0-9],\sR[0-9]+`
c9 := e&(-19) < 0
@@ -268,7 +268,7 @@ func CmpToZero(a, b, d int32, e, f int64, deOptC0, deOptC1 bool) int32 {
}
}
func CmpLogicalToZero(a, b, c uint32, d, e uint64) uint64 {
func CmpLogicalToZero(a, b, c uint32, d, e, f, g uint64) uint64 {
// ppc64x:"ANDCC",-"CMPW"
// wasm:"I64Eqz",-"I32Eqz",-"I64ExtendI32U",-"I32WrapI64"
@@ -289,7 +289,7 @@ func CmpLogicalToZero(a, b, c uint32, d, e uint64) uint64 {
}
// ppc64x:"ORCC",-"CMP"
// wasm:"I64Eqz",-"I32Eqz",-"I64ExtendI32U",-"I32WrapI64"
if d|e == 0 {
if f|g == 0 {
return 1
}

View File

@@ -95,6 +95,7 @@ func moveArchLowering1(b []byte, x *[1]byte) {
_ = b[1]
// amd64:-".*memmove"
// arm64:-".*memmove"
// loong64:-".*memmove"
// ppc64x:-".*memmove"
copy(b, x[:])
}
@@ -103,6 +104,7 @@ func moveArchLowering2(b []byte, x *[2]byte) {
_ = b[2]
// amd64:-".*memmove"
// arm64:-".*memmove"
// loong64:-".*memmove"
// ppc64x:-".*memmove"
copy(b, x[:])
}
@@ -111,6 +113,7 @@ func moveArchLowering4(b []byte, x *[4]byte) {
_ = b[4]
// amd64:-".*memmove"
// arm64:-".*memmove"
// loong64:-".*memmove"
// ppc64x:-".*memmove"
copy(b, x[:])
}

View File

@@ -54,11 +54,13 @@ func DivPow2(f1, f2, f3 float64) (float64, float64, float64) {
func indexLoad(b0 []float32, b1 float32, idx int) float32 {
// arm64:`FMOVS\s\(R[0-9]+\)\(R[0-9]+<<2\),\sF[0-9]+`
// loong64:`MOVF\s\(R[0-9]+\)\(R[0-9]+\),\sF[0-9]+`
return b0[idx] * b1
}
func indexStore(b0 []float64, b1 float64, idx int) {
// arm64:`FMOVD\sF[0-9]+,\s\(R[0-9]+\)\(R[0-9]+<<3\)`
// loong64:`MOVD\sF[0-9]+,\s\(R[0-9]+\)\(R[0-9]+\)`
b0[idx] = b1
}
@@ -70,6 +72,7 @@ func FusedAdd32(x, y, z float32) float32 {
// s390x:"FMADDS\t"
// ppc64x:"FMADDS\t"
// arm64:"FMADDS"
// loong64:"FMADDF\t"
// riscv64:"FMADDS\t"
return x*y + z
}
@@ -78,11 +81,13 @@ func FusedSub32_a(x, y, z float32) float32 {
// s390x:"FMSUBS\t"
// ppc64x:"FMSUBS\t"
// riscv64:"FMSUBS\t"
// loong64:"FMSUBF\t"
return x*y - z
}
func FusedSub32_b(x, y, z float32) float32 {
// arm64:"FMSUBS"
// loong64:"FNMSUBF\t"
// riscv64:"FNMSUBS\t"
return z - x*y
}
@@ -91,6 +96,7 @@ func FusedAdd64(x, y, z float64) float64 {
// s390x:"FMADD\t"
// ppc64x:"FMADD\t"
// arm64:"FMADDD"
// loong64:"FMADDD\t"
// riscv64:"FMADDD\t"
return x*y + z
}
@@ -99,11 +105,13 @@ func FusedSub64_a(x, y, z float64) float64 {
// s390x:"FMSUB\t"
// ppc64x:"FMSUB\t"
// riscv64:"FMSUBD\t"
// loong64:"FMSUBD\t"
return x*y - z
}
func FusedSub64_b(x, y, z float64) float64 {
// arm64:"FMSUBD"
// loong64:"FNMSUBD\t"
// riscv64:"FNMSUBD\t"
return z - x*y
}
@@ -164,6 +172,7 @@ func ArrayCopy(a [16]byte) (b [16]byte) {
func Float64Min(a, b float64) float64 {
// amd64:"MINSD"
// arm64:"FMIND"
// loong64:"FMIND"
// riscv64:"FMIN"
// ppc64/power9:"XSMINJDP"
// ppc64/power10:"XSMINJDP"
@@ -173,6 +182,7 @@ func Float64Min(a, b float64) float64 {
func Float64Max(a, b float64) float64 {
// amd64:"MINSD"
// arm64:"FMAXD"
// loong64:"FMAXD"
// riscv64:"FMAX"
// ppc64/power9:"XSMAXJDP"
// ppc64/power10:"XSMAXJDP"
@@ -182,6 +192,7 @@ func Float64Max(a, b float64) float64 {
func Float32Min(a, b float32) float32 {
// amd64:"MINSS"
// arm64:"FMINS"
// loong64:"FMINF"
// riscv64:"FMINS"
// ppc64/power9:"XSMINJDP"
// ppc64/power10:"XSMINJDP"
@@ -191,6 +202,7 @@ func Float32Min(a, b float32) float32 {
func Float32Max(a, b float32) float32 {
// amd64:"MINSS"
// arm64:"FMAXS"
// loong64:"FMAXF"
// riscv64:"FMAXS"
// ppc64/power9:"XSMAXJDP"
// ppc64/power10:"XSMAXJDP"
@@ -227,3 +239,12 @@ func Float64DenormalFloat32Constant() float64 {
// ppc64x:"FMOVD\t[$]f64\\.3800000000000000\\(SB\\)"
return 0x1p-127
}
func Float64ConstantStore(p *float64) {
// amd64: "MOVQ\t[$]4617801906721357038"
*p = 5.432
}
func Float32ConstantStore(p *float32) {
// amd64: "MOVL\t[$]1085133554"
*p = 5.432
}

View File

@@ -0,0 +1,17 @@
// asmcheck
// Copyright 2023 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
func f(x, y int, p *int) {
// amd64:`MOVQ\sAX, BX`
h(8, x)
*p = y
}
//go:noinline
func h(a, b int) {
}

View File

@@ -0,0 +1,52 @@
// asmcheck
// Copyright 2024 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
type T1 struct {
x string
}
func f1() *T1 {
// amd64:-`MOVQ\s[$]0`,-`MOVUPS\sX15`
return &T1{}
}
type T2 struct {
x, y string
}
func f2() *T2 {
// amd64:-`MOVQ\s[$]0`,-`MOVUPS\sX15`
return &T2{}
}
type T3 struct {
x complex128
}
func f3() *T3 {
// amd64:-`MOVQ\s[$]0`,-`MOVUPS\sX15`
return &T3{}
}
type T4 struct {
x []byte
}
func f4() *T4 {
// amd64:-`MOVQ\s[$]0`,-`MOVUPS\sX15`
return &T4{}
}
type T5 struct {
x any
}
func f5() *T5 {
// amd64:-`MOVQ\s[$]0`,-`MOVUPS\sX15`
return &T5{}
}

View File

@@ -0,0 +1,13 @@
// asmcheck
// Copyright 2024 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
func calc(a uint64) uint64 {
v := a >> 20 & 0x7f
// amd64: `SHRQ\s\$17, AX$`, `ANDL\s\$1016, AX$`
return v << 3
}

View File

@@ -74,7 +74,7 @@ func LookupStringConversionKeyedArrayLit(m map[[2]string]int, bytes []byte) int
func MapClearReflexive(m map[int]int) {
// amd64:`.*runtime\.mapclear`
// amd64:-`.*runtime\.mapiterinit`
// amd64:-`.*runtime\.(mapiterinit|mapIterStart)`
for k := range m {
delete(m, k)
}
@@ -83,7 +83,7 @@ func MapClearReflexive(m map[int]int) {
func MapClearIndirect(m map[int]int) {
s := struct{ m map[int]int }{m: m}
// amd64:`.*runtime\.mapclear`
// amd64:-`.*runtime\.mapiterinit`
// amd64:-`.*runtime\.(mapiterinit|mapIterStart)`
for k := range s.m {
delete(s.m, k)
}
@@ -91,14 +91,14 @@ func MapClearIndirect(m map[int]int) {
func MapClearPointer(m map[*byte]int) {
// amd64:`.*runtime\.mapclear`
// amd64:-`.*runtime\.mapiterinit`
// amd64:-`.*runtime\.(mapiterinit|mapIterStart)`
for k := range m {
delete(m, k)
}
}
func MapClearNotReflexive(m map[float64]int) {
// amd64:`.*runtime\.mapiterinit`
// amd64:`.*runtime\.(mapiterinit|mapIterStart)`
// amd64:-`.*runtime\.mapclear`
for k := range m {
delete(m, k)
@@ -106,7 +106,7 @@ func MapClearNotReflexive(m map[float64]int) {
}
func MapClearInterface(m map[interface{}]int) {
// amd64:`.*runtime\.mapiterinit`
// amd64:`.*runtime\.(mapiterinit|mapIterStart)`
// amd64:-`.*runtime\.mapclear`
for k := range m {
delete(m, k)
@@ -115,7 +115,7 @@ func MapClearInterface(m map[interface{}]int) {
func MapClearSideEffect(m map[int]int) int {
k := 0
// amd64:`.*runtime\.mapiterinit`
// amd64:`.*runtime\.(mapiterinit|mapIterStart)`
// amd64:-`.*runtime\.mapclear`
for k = range m {
delete(m, k)

View File

@@ -132,6 +132,7 @@ func fma(x, y, z float64) float64 {
// amd64:"VFMADD231SD"
// arm/6:"FMULAD"
// arm64:"FMADDD"
// loong64:"FMADDD"
// s390x:"FMADD"
// ppc64x:"FMADD"
// riscv64:"FMADDD"
@@ -156,6 +157,7 @@ func fnma(x, y, z float64) float64 {
func fromFloat64(f64 float64) uint64 {
// amd64:"MOVQ\tX.*, [^X].*"
// arm64:"FMOVD\tF.*, R.*"
// loong64:"MOVV\tF.*, R.*"
// ppc64x:"MFVSRD"
// mips64/hardfloat:"MOVV\tF.*, R.*"
return math.Float64bits(f64+1) + 1
@@ -164,6 +166,7 @@ func fromFloat64(f64 float64) uint64 {
func fromFloat32(f32 float32) uint32 {
// amd64:"MOVL\tX.*, [^X].*"
// arm64:"FMOVS\tF.*, R.*"
// loong64:"MOVW\tF.*, R.*"
// mips64/hardfloat:"MOVW\tF.*, R.*"
return math.Float32bits(f32+1) + 1
}
@@ -171,6 +174,7 @@ func fromFloat32(f32 float32) uint32 {
func toFloat64(u64 uint64) float64 {
// amd64:"MOVQ\t[^X].*, X.*"
// arm64:"FMOVD\tR.*, F.*"
// loong64:"MOVV\tR.*, F.*"
// ppc64x:"MTVSRD"
// mips64/hardfloat:"MOVV\tR.*, F.*"
return math.Float64frombits(u64+1) + 1
@@ -179,6 +183,7 @@ func toFloat64(u64 uint64) float64 {
func toFloat32(u32 uint32) float32 {
// amd64:"MOVL\t[^X].*, X.*"
// arm64:"FMOVS\tR.*, F.*"
// loong64:"MOVW\tR.*, F.*"
// mips64/hardfloat:"MOVW\tR.*, F.*"
return math.Float32frombits(u32+1) + 1
}

View File

@@ -17,6 +17,7 @@ func LeadingZeros(n uint) int {
// amd64/v3:"LZCNTQ", -"BSRQ"
// s390x:"FLOGR"
// arm:"CLZ" arm64:"CLZ"
// loong64:"CLZV",-"SUB"
// mips:"CLZ"
// wasm:"I64Clz"
// ppc64x:"CNTLZD"
@@ -28,6 +29,7 @@ func LeadingZeros64(n uint64) int {
// amd64/v3:"LZCNTQ", -"BSRQ"
// s390x:"FLOGR"
// arm:"CLZ" arm64:"CLZ"
// loong64:"CLZV",-"SUB"
// mips:"CLZ"
// wasm:"I64Clz"
// ppc64x:"CNTLZD"
@@ -39,6 +41,7 @@ func LeadingZeros32(n uint32) int {
// amd64/v3: "LZCNTL",- "BSRL"
// s390x:"FLOGR"
// arm:"CLZ" arm64:"CLZW"
// loong64:"CLZW",-"SUB"
// mips:"CLZ"
// wasm:"I64Clz"
// ppc64x:"CNTLZW"
@@ -50,6 +53,7 @@ func LeadingZeros16(n uint16) int {
// amd64/v3: "LZCNTL",- "BSRL"
// s390x:"FLOGR"
// arm:"CLZ" arm64:"CLZ"
// loong64:"CLZV"
// mips:"CLZ"
// wasm:"I64Clz"
// ppc64x:"CNTLZD"
@@ -61,6 +65,7 @@ func LeadingZeros8(n uint8) int {
// amd64/v3: "LZCNTL",- "BSRL"
// s390x:"FLOGR"
// arm:"CLZ" arm64:"CLZ"
// loong64:"CLZV"
// mips:"CLZ"
// wasm:"I64Clz"
// ppc64x:"CNTLZD"
@@ -76,6 +81,7 @@ func Len(n uint) int {
// amd64/v3: "LZCNTQ"
// s390x:"FLOGR"
// arm:"CLZ" arm64:"CLZ"
// loong64:"CLZV"
// mips:"CLZ"
// wasm:"I64Clz"
// ppc64x:"SUBC","CNTLZD"
@@ -87,6 +93,7 @@ func Len64(n uint64) int {
// amd64/v3: "LZCNTQ"
// s390x:"FLOGR"
// arm:"CLZ" arm64:"CLZ"
// loong64:"CLZV"
// mips:"CLZ"
// wasm:"I64Clz"
// ppc64x:"SUBC","CNTLZD"
@@ -94,15 +101,22 @@ func Len64(n uint64) int {
}
func SubFromLen64(n uint64) int {
// loong64:"CLZV",-"ADD"
// ppc64x:"CNTLZD",-"SUBC"
return 64 - bits.Len64(n)
}
func CompareWithLen64(n uint64) bool {
// loong64:"CLZV",-"ADD",-"[$]64",-"[$]9"
return bits.Len64(n) < 9
}
func Len32(n uint32) int {
// amd64/v1,amd64/v2:"BSRQ","LEAQ",-"CMOVQEQ"
// amd64/v3: "LZCNTL"
// s390x:"FLOGR"
// arm:"CLZ" arm64:"CLZ"
// loong64:"CLZW"
// mips:"CLZ"
// wasm:"I64Clz"
// ppc64x: "CNTLZW"
@@ -114,6 +128,7 @@ func Len16(n uint16) int {
// amd64/v3: "LZCNTL"
// s390x:"FLOGR"
// arm:"CLZ" arm64:"CLZ"
// loong64:"CLZV"
// mips:"CLZ"
// wasm:"I64Clz"
// ppc64x:"SUBC","CNTLZD"
@@ -125,6 +140,7 @@ func Len8(n uint8) int {
// amd64/v3: "LZCNTL"
// s390x:"FLOGR"
// arm:"CLZ" arm64:"CLZ"
// loong64:"CLZV"
// mips:"CLZ"
// wasm:"I64Clz"
// ppc64x:"SUBC","CNTLZD"
@@ -140,6 +156,7 @@ func OnesCount(n uint) int {
// amd64/v2:-".*x86HasPOPCNT" amd64/v3:-".*x86HasPOPCNT"
// amd64:"POPCNTQ"
// arm64:"VCNT","VUADDLV"
// loong64:"VPCNTV"
// s390x:"POPCNT"
// ppc64x:"POPCNTD"
// wasm:"I64Popcnt"
@@ -150,6 +167,7 @@ func OnesCount64(n uint64) int {
// amd64/v2:-".*x86HasPOPCNT" amd64/v3:-".*x86HasPOPCNT"
// amd64:"POPCNTQ"
// arm64:"VCNT","VUADDLV"
// loong64:"VPCNTV"
// s390x:"POPCNT"
// ppc64x:"POPCNTD"
// wasm:"I64Popcnt"
@@ -160,6 +178,7 @@ func OnesCount32(n uint32) int {
// amd64/v2:-".*x86HasPOPCNT" amd64/v3:-".*x86HasPOPCNT"
// amd64:"POPCNTL"
// arm64:"VCNT","VUADDLV"
// loong64:"VPCNTW"
// s390x:"POPCNT"
// ppc64x:"POPCNTW"
// wasm:"I64Popcnt"
@@ -170,6 +189,7 @@ func OnesCount16(n uint16) int {
// amd64/v2:-".*x86HasPOPCNT" amd64/v3:-".*x86HasPOPCNT"
// amd64:"POPCNTL"
// arm64:"VCNT","VUADDLV"
// loong64:"VPCNTH"
// s390x:"POPCNT"
// ppc64x:"POPCNTW"
// wasm:"I64Popcnt"
@@ -183,6 +203,35 @@ func OnesCount8(n uint8) int {
return bits.OnesCount8(n)
}
// ------------------ //
// bits.Reverse //
// ------------------ //
func Reverse(n uint) uint {
// loong64:"BITREVV"
return bits.Reverse(n)
}
func Reverse64(n uint64) uint64 {
// loong64:"BITREVV"
return bits.Reverse64(n)
}
func Reverse32(n uint32) uint32 {
// loong64:"BITREVW"
return bits.Reverse32(n)
}
func Reverse16(n uint16) uint16 {
// loong64:"BITREV4B","REVB2H"
return bits.Reverse16(n)
}
func Reverse8(n uint8) uint8 {
// loong64:"BITREV4B"
return bits.Reverse8(n)
}
// ----------------------- //
// bits.ReverseBytes //
// ----------------------- //
@@ -192,6 +241,7 @@ func ReverseBytes(n uint) uint {
// 386:"BSWAPL"
// s390x:"MOVDBR"
// arm64:"REV"
// loong64:"REVBV"
return bits.ReverseBytes(n)
}
@@ -201,6 +251,7 @@ func ReverseBytes64(n uint64) uint64 {
// s390x:"MOVDBR"
// arm64:"REV"
// ppc64x/power10: "BRD"
// loong64:"REVBV"
return bits.ReverseBytes64(n)
}
@@ -209,6 +260,7 @@ func ReverseBytes32(n uint32) uint32 {
// 386:"BSWAPL"
// s390x:"MOVWBR"
// arm64:"REVW"
// loong64:"REVB2W"
// ppc64x/power10: "BRW"
return bits.ReverseBytes32(n)
}
@@ -219,6 +271,7 @@ func ReverseBytes16(n uint16) uint16 {
// arm/5:"SLL","SRL","ORR"
// arm/6:"REV16"
// arm/7:"REV16"
// loong64:"REVB2H"
// ppc64x/power10: "BRH"
return bits.ReverseBytes16(n)
}
@@ -230,7 +283,9 @@ func ReverseBytes16(n uint16) uint16 {
func RotateLeft64(n uint64) uint64 {
// amd64:"ROLQ"
// arm64:"ROR"
// loong64:"ROTRV"
// ppc64x:"ROTL"
// riscv64:"RORI"
// s390x:"RISBGZ\t[$]0, [$]63, [$]37, "
// wasm:"I64Rotl"
return bits.RotateLeft64(n, 37)
@@ -240,7 +295,9 @@ func RotateLeft32(n uint32) uint32 {
// amd64:"ROLL" 386:"ROLL"
// arm:`MOVW\tR[0-9]+@>23`
// arm64:"RORW"
// loong64:"ROTR\t"
// ppc64x:"ROTLW"
// riscv64:"RORIW"
// s390x:"RLL"
// wasm:"I32Rotl"
return bits.RotateLeft32(n, 9)
@@ -249,19 +306,23 @@ func RotateLeft32(n uint32) uint32 {
func RotateLeft16(n uint16, s int) uint16 {
// amd64:"ROLW" 386:"ROLW"
// arm64:"RORW",-"CSEL"
// loong64:"ROTR\t","SLLV"
return bits.RotateLeft16(n, s)
}
func RotateLeft8(n uint8, s int) uint8 {
// amd64:"ROLB" 386:"ROLB"
// arm64:"LSL","LSR",-"CSEL"
// loong64:"OR","SLLV","SRLV"
return bits.RotateLeft8(n, s)
}
func RotateLeftVariable(n uint, m int) uint {
// amd64:"ROLQ"
// arm64:"ROR"
// loong64:"ROTRV"
// ppc64x:"ROTL"
// riscv64:"ROL"
// s390x:"RLLG"
// wasm:"I64Rotl"
return bits.RotateLeft(n, m)
@@ -270,7 +331,9 @@ func RotateLeftVariable(n uint, m int) uint {
func RotateLeftVariable64(n uint64, m int) uint64 {
// amd64:"ROLQ"
// arm64:"ROR"
// loong64:"ROTRV"
// ppc64x:"ROTL"
// riscv64:"ROL"
// s390x:"RLLG"
// wasm:"I64Rotl"
return bits.RotateLeft64(n, m)
@@ -280,7 +343,9 @@ func RotateLeftVariable32(n uint32, m int) uint32 {
// arm:`MOVW\tR[0-9]+@>R[0-9]+`
// amd64:"ROLL"
// arm64:"RORW"
// loong64:"ROTR\t"
// ppc64x:"ROTLW"
// riscv64:"ROLW"
// s390x:"RLL"
// wasm:"I32Rotl"
return bits.RotateLeft32(n, m)
@@ -296,6 +361,7 @@ func TrailingZeros(n uint) int {
// 386:"BSFL"
// arm:"CLZ"
// arm64:"RBIT","CLZ"
// loong64:"CTZV"
// s390x:"FLOGR"
// ppc64x/power8:"ANDN","POPCNTD"
// ppc64x/power9: "CNTTZD"
@@ -308,6 +374,7 @@ func TrailingZeros64(n uint64) int {
// amd64/v3:"TZCNTQ"
// 386:"BSFL"
// arm64:"RBIT","CLZ"
// loong64:"CTZV"
// s390x:"FLOGR"
// ppc64x/power8:"ANDN","POPCNTD"
// ppc64x/power9: "CNTTZD"
@@ -327,6 +394,7 @@ func TrailingZeros32(n uint32) int {
// 386:"BSFL"
// arm:"CLZ"
// arm64:"RBITW","CLZW"
// loong64:"CTZW"
// s390x:"FLOGR","MOVWZ"
// ppc64x/power8:"ANDN","POPCNTW"
// ppc64x/power9: "CNTTZW"
@@ -339,6 +407,7 @@ func TrailingZeros16(n uint16) int {
// 386:"BSFL\t"
// arm:"ORR\t\\$65536","CLZ",-"MOVHU\tR"
// arm64:"ORR\t\\$65536","RBITW","CLZW",-"MOVHU\tR",-"RBIT\t",-"CLZ\t"
// loong64:"CTZV"
// s390x:"FLOGR","OR\t\\$65536"
// ppc64x/power8:"POPCNTD","ORIS\\t\\$1"
// ppc64x/power9:"CNTTZD","ORIS\\t\\$1"
@@ -351,6 +420,7 @@ func TrailingZeros8(n uint8) int {
// 386:"BSFL"
// arm:"ORR\t\\$256","CLZ",-"MOVBU\tR"
// arm64:"ORR\t\\$256","RBITW","CLZW",-"MOVBU\tR",-"RBIT\t",-"CLZ\t"
// loong64:"CTZV"
// s390x:"FLOGR","OR\t\\$256"
// wasm:"I64Ctz"
return bits.TrailingZeros8(n)

View File

@@ -19,6 +19,7 @@ func load_le64(b []byte) uint64 {
// amd64:`MOVQ\s\(.*\),`,-`MOV[BWL]\t[^$]`,-`OR`
// s390x:`MOVDBR\s\(.*\),`
// arm64:`MOVD\s\(R[0-9]+\),`,-`MOV[BHW]`
// loong64:`MOVBU\s\(R[0-9]+\),`
// ppc64le:`MOVD\s`,-`MOV[BHW]Z`
// ppc64:`MOVDBR\s`,-`MOV[BHW]Z`
return binary.LittleEndian.Uint64(b)
@@ -28,6 +29,7 @@ func load_le64_idx(b []byte, idx int) uint64 {
// amd64:`MOVQ\s\(.*\)\(.*\*1\),`,-`MOV[BWL]\t[^$]`,-`OR`
// s390x:`MOVDBR\s\(.*\)\(.*\*1\),`
// arm64:`MOVD\s\(R[0-9]+\)\(R[0-9]+\),`,-`MOV[BHW]`
// loong64:`MOVBU\s\(R[0-9]+\)\(R[0-9]+\),`
// ppc64le:`MOVD\s`,-`MOV[BHW]Z\s`
// ppc64:`MOVDBR\s`,-`MOV[BHW]Z\s`
return binary.LittleEndian.Uint64(b[idx:])
@@ -38,6 +40,7 @@ func load_le32(b []byte) uint32 {
// 386:`MOVL\s\(.*\),`,-`MOV[BW]`,-`OR`
// s390x:`MOVWBR\s\(.*\),`
// arm64:`MOVWU\s\(R[0-9]+\),`,-`MOV[BH]`
// loong64:`MOVBU\s\(R[0-9]+\),`
// ppc64le:`MOVWZ\s`,-`MOV[BH]Z\s`
// ppc64:`MOVWBR\s`,-`MOV[BH]Z\s`
return binary.LittleEndian.Uint32(b)
@@ -48,6 +51,7 @@ func load_le32_idx(b []byte, idx int) uint32 {
// 386:`MOVL\s\(.*\)\(.*\*1\),`,-`MOV[BW]`,-`OR`
// s390x:`MOVWBR\s\(.*\)\(.*\*1\),`
// arm64:`MOVWU\s\(R[0-9]+\)\(R[0-9]+\),`,-`MOV[BH]`
// loong64:`MOVBU\s\(R[0-9]+\)\(R[0-9]+\),`
// ppc64le:`MOVWZ\s`,-`MOV[BH]Z\s`
// ppc64:`MOVWBR\s`,-`MOV[BH]Z\s'
return binary.LittleEndian.Uint32(b[idx:])
@@ -57,6 +61,7 @@ func load_le16(b []byte) uint16 {
// amd64:`MOVWLZX\s\(.*\),`,-`MOVB`,-`OR`
// ppc64le:`MOVHZ\s`,-`MOVBZ`
// arm64:`MOVHU\s\(R[0-9]+\),`,-`MOVB`
// loong64:`MOVBU\s\(R[0-9]+\),`
// s390x:`MOVHBR\s\(.*\),`
// ppc64:`MOVHBR\s`,-`MOVBZ`
return binary.LittleEndian.Uint16(b)
@@ -67,6 +72,7 @@ func load_le16_idx(b []byte, idx int) uint16 {
// ppc64le:`MOVHZ\s`,-`MOVBZ`
// ppc64:`MOVHBR\s`,-`MOVBZ`
// arm64:`MOVHU\s\(R[0-9]+\)\(R[0-9]+\),`,-`MOVB`
// loong64:`MOVBU\s\(R[0-9]+\)\(R[0-9]+\),`
// s390x:`MOVHBR\s\(.*\)\(.*\*1\),`
return binary.LittleEndian.Uint16(b[idx:])
}
@@ -938,3 +944,29 @@ func issue66413(p *struct {
p.c = true
p.d = 12
}
func issue70300(v uint64) (b [8]byte) {
// amd64:"MOVQ",-"MOVB"
b[0] = byte(v)
b[1] = byte(v >> 8)
b[2] = byte(v >> 16)
b[3] = byte(v >> 24)
b[4] = byte(v >> 32)
b[5] = byte(v >> 40)
b[6] = byte(v >> 48)
b[7] = byte(v >> 56)
return b
}
func issue70300Reverse(v uint64) (b [8]byte) {
// amd64:"MOVQ",-"MOVB"
b[7] = byte(v >> 56)
b[6] = byte(v >> 48)
b[5] = byte(v >> 40)
b[4] = byte(v >> 32)
b[3] = byte(v >> 24)
b[2] = byte(v >> 16)
b[1] = byte(v >> 8)
b[0] = byte(v)
return b
}

View File

@@ -462,12 +462,6 @@ func checkMergedShifts64(a [256]uint32, b [256]uint64, c [256]byte, v uint64) {
a[2] = a[v>>25&0x7F]
// ppc64x: -"CLRLSLDI", "RLWNM\t[$]3, R[0-9]+, [$]29, [$]29, R[0-9]+"
a[3] = a[(v>>31)&0x01]
// ppc64x: "SRD", "CLRLSLDI", -"RLWNM"
a[4] = a[(v>>30)&0x07]
// ppc64x: "SRD", "CLRLSLDI", -"RLWNM"
a[5] = a[(v>>32)&0x01]
// ppc64x: "SRD", "CLRLSLDI", -"RLWNM"
a[6] = a[(v>>34)&0x03]
// ppc64x: -"CLRLSLDI", "RLWNM\t[$]12, R[0-9]+, [$]21, [$]28, R[0-9]+"
b[0] = b[uint8(v>>23)]
// ppc64x: -"CLRLSLDI", "RLWNM\t[$]15, R[0-9]+, [$]21, [$]28, R[0-9]+"
@@ -476,7 +470,7 @@ func checkMergedShifts64(a [256]uint32, b [256]uint64, c [256]byte, v uint64) {
b[2] = b[((uint64((uint32(v) >> 21)) & 0x3f) << 4)]
// ppc64x: "RLWNM\t[$]11, R[0-9]+, [$]10, [$]15"
c[0] = c[((v>>5)&0x3F)<<16]
// ppc64x: "RLWNM\t[$]0, R[0-9]+, [$]19, [$]24"
// ppc64x: "ANDCC\t[$]8064,"
c[1] = c[((v>>7)&0x3F)<<7]
}
@@ -520,3 +514,20 @@ func checkShiftToMask(u []uint64, s []int64) {
// amd64:-"SHR",-"SHL","ANDQ"
u[1] = u[1] << 5 >> 5
}
//
// Left shift with addition.
//
func checkLeftShiftWithAddition(a int64, b int64) int64 {
// riscv64/rva20u64: "SLLI","ADD"
// riscv64/rva22u64: "SH1ADD"
a = a + b<<1
// riscv64/rva20u64: "SLLI","ADD"
// riscv64/rva22u64: "SH2ADD"
a = a + b<<2
// riscv64/rva20u64: "SLLI","ADD"
// riscv64/rva22u64: "SH3ADD"
a = a + b<<3
return a
}

View File

@@ -47,6 +47,7 @@ func SliceExtensionConst(s []int) []int {
// amd64:-`.*runtime\.makeslice`
// amd64:-`.*runtime\.panicmakeslicelen`
// amd64:"MOVUPS\tX15"
// loong64:-`.*runtime\.memclrNoHeapPointers`
// ppc64x:-`.*runtime\.memclrNoHeapPointers`
// ppc64x:-`.*runtime\.makeslice`
// ppc64x:-`.*runtime\.panicmakeslicelen`
@@ -58,6 +59,7 @@ func SliceExtensionConstInt64(s []int) []int {
// amd64:-`.*runtime\.makeslice`
// amd64:-`.*runtime\.panicmakeslicelen`
// amd64:"MOVUPS\tX15"
// loong64:-`.*runtime\.memclrNoHeapPointers`
// ppc64x:-`.*runtime\.memclrNoHeapPointers`
// ppc64x:-`.*runtime\.makeslice`
// ppc64x:-`.*runtime\.panicmakeslicelen`
@@ -69,6 +71,7 @@ func SliceExtensionConstUint64(s []int) []int {
// amd64:-`.*runtime\.makeslice`
// amd64:-`.*runtime\.panicmakeslicelen`
// amd64:"MOVUPS\tX15"
// loong64:-`.*runtime\.memclrNoHeapPointers`
// ppc64x:-`.*runtime\.memclrNoHeapPointers`
// ppc64x:-`.*runtime\.makeslice`
// ppc64x:-`.*runtime\.panicmakeslicelen`
@@ -80,16 +83,18 @@ func SliceExtensionConstUint(s []int) []int {
// amd64:-`.*runtime\.makeslice`
// amd64:-`.*runtime\.panicmakeslicelen`
// amd64:"MOVUPS\tX15"
// loong64:-`.*runtime\.memclrNoHeapPointers`
// ppc64x:-`.*runtime\.memclrNoHeapPointers`
// ppc64x:-`.*runtime\.makeslice`
// ppc64x:-`.*runtime\.panicmakeslicelen`
return append(s, make([]int, uint(1<<2))...)
}
// On ppc64x continue to use memclrNoHeapPointers
// On ppc64x and loong64 continue to use memclrNoHeapPointers
// for sizes >= 512.
func SliceExtensionConst512(s []int) []int {
// amd64:-`.*runtime\.memclrNoHeapPointers`
// loong64:`.*runtime\.memclrNoHeapPointers`
// ppc64x:`.*runtime\.memclrNoHeapPointers`
return append(s, make([]int, 1<<9)...)
}

31
test/codegen/spills.go Normal file
View File

@@ -0,0 +1,31 @@
// asmcheck
// Copyright 2024 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
func i64(a, b int64) int64 { // arm64:`STP\s`,`LDP\s`
g()
return a + b
}
func i32(a, b int32) int32 { // arm64:`STPW`,`LDPW`
g()
return a + b
}
func f64(a, b float64) float64 { // arm64:`FSTPD`,`FLDPD`
g()
return a + b
}
func f32(a, b float32) float32 { // arm64:`FSTPS`,`FLDPS`
g()
return a + b
}
//go:noinline
func g() {
}

View File

@@ -26,6 +26,11 @@ func ToByteSlice() []byte { // Issue #24698
return []byte("foo")
}
func ConvertToByteSlice(a, b, c string) []byte {
// amd64:`.*runtime.concatbyte3`
return []byte(a + b + c)
}
// Loading from read-only symbols should get transformed into constants.
func ConstantLoad() {
// 12592 = 0x3130

View File

@@ -0,0 +1,67 @@
// asmcheck
// Copyright 2024 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
type Ix interface {
X()
}
type Iy interface {
Y()
}
type Iz interface {
Z()
}
func swXYZ(a Ix) {
switch t := a.(type) {
case Iy: // amd64:-".*typeAssert"
t.Y()
case Iz: // amd64:-".*typeAssert"
t.Z()
}
}
type Ig[T any] interface {
G() T
}
func swGYZ[T any](a Ig[T]) {
switch t := a.(type) {
case Iy: // amd64:-".*typeAssert"
t.Y()
case Iz: // amd64:-".*typeAssert"
t.Z()
case interface{ G() T }: // amd64:-".*typeAssert",-".*assertE2I\\(",".*assertE2I2"
t.G()
}
}
func swE2G[T any](a any) {
switch t := a.(type) {
case Iy:
t.Y()
case Ig[T]: // amd64:-".*assertE2I\\(",".*assertE2I2"
t.G()
}
}
func swI2G[T any](a Ix) {
switch t := a.(type) {
case Iy:
t.Y()
case Ig[T]: // amd64:-".*assertE2I\\(",".*assertE2I2"
t.G()
}
}
func swCaller() {
swGYZ[int]((Ig[int])(nil))
swE2G[int]((Ig[int])(nil))
swI2G[int]((Ix)(nil))
}

16
test/codegen/unsafe.go Normal file
View File

@@ -0,0 +1,16 @@
// asmcheck
// Copyright 2024 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 "unsafe"
func f(p unsafe.Pointer, x, y uintptr) int64 {
p = unsafe.Pointer(uintptr(p) + x + y)
// amd64:`MOVQ\s\(.*\)\(.*\*1\), `
// arm64:`MOVD\s\(R[0-9]+\)\(R[0-9]+\), `
return *(*int64)(p)
}

View File

@@ -54,6 +54,16 @@ func combine4slice(p *[4][]byte, a, b, c, d []byte) {
p[3] = d
}
func trickyWriteNil(p *int, q **int) {
if p == nil {
// We change "= p" to "= 0" in the prove pass, which
// means we have one less pointer that needs to go
// into the write barrier buffer.
// amd64:`.*runtime[.]gcWriteBarrier1`
*q = p
}
}
type S struct {
a, b string
c *int