]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix sign extension of paired 32-bit loads on arm64
authorKeith Randall <khr@golang.org>
Sat, 15 Feb 2025 00:13:44 +0000 (16:13 -0800)
committerKeith Randall <khr@golang.org>
Sat, 15 Feb 2025 15:53:28 +0000 (07:53 -0800)
Fixes #71759

Change-Id: Iab05294ac933cc9972949158d3fe2bdc3073df5e
Reviewed-on: https://go-review.googlesource.com/c/go/+/649895
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
src/cmd/compile/internal/arm64/ssa.go
src/cmd/compile/internal/ssa/_gen/ARM64Ops.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/pair.go
test/codegen/memcombine.go
test/fixedbugs/issue71759.go [new file with mode: 0644]

index 7bf8051bef5e7b787aa8285bb27dfdb7a02eefd4..0f5c5a17bd5fa2ca6fa838a9e1b1ae0fe432b14b 100644 (file)
@@ -516,7 +516,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                ssagen.AddAux(&p.From, v)
                p.To.Type = obj.TYPE_REG
                p.To.Reg = v.Reg()
-       case ssa.OpARM64LDP, ssa.OpARM64LDPW, ssa.OpARM64FLDPD, ssa.OpARM64FLDPS:
+       case ssa.OpARM64LDP, ssa.OpARM64LDPW, ssa.OpARM64LDPSW, ssa.OpARM64FLDPD, ssa.OpARM64FLDPS:
                p := s.Prog(v.Op.Asm())
                p.From.Type = obj.TYPE_MEM
                p.From.Reg = v.Args[0].Reg()
index 4c4e610dba9413494d02e488797706522325d65b..53e6dbec3f159ff244e2371696cf90a04a0859ae 100644 (file)
@@ -388,7 +388,8 @@ func init() {
                // arg1=mem
                // Returns the tuple <x,y>.
                {name: "LDP", argLength: 2, reg: gpload2, aux: "SymOff", asm: "LDP", typ: "(UInt64,UInt64)", faultOnNilArg0: true, symEffect: "Read"},       // T=int64 (gp reg destination)
-               {name: "LDPW", argLength: 2, reg: gpload2, aux: "SymOff", asm: "LDPW", typ: "(UInt32,UInt32)", faultOnNilArg0: true, symEffect: "Read"},     // T=int32 (gp reg destination) ??? extension
+               {name: "LDPW", argLength: 2, reg: gpload2, aux: "SymOff", asm: "LDPW", typ: "(UInt32,UInt32)", faultOnNilArg0: true, symEffect: "Read"},     // T=int32 (gp reg destination) unsigned extension
+               {name: "LDPSW", argLength: 2, reg: gpload2, aux: "SymOff", asm: "LDPSW", typ: "(Int32,Int32)", faultOnNilArg0: true, symEffect: "Read"},     // T=int32 (gp reg destination) signed extension
                {name: "FLDPD", argLength: 2, reg: fpload2, aux: "SymOff", asm: "FLDPD", typ: "(Float64,Float64)", faultOnNilArg0: true, symEffect: "Read"}, // T=float64 (fp reg destination)
                {name: "FLDPS", argLength: 2, reg: fpload2, aux: "SymOff", asm: "FLDPS", typ: "(Float32,Float32)", faultOnNilArg0: true, symEffect: "Read"}, // T=float32 (fp reg destination)
 
index 19a748eb08f5482f591d350fd1184749acbd1942..718f4c93821dcf5720976c887e891d2622bb54cf 100644 (file)
@@ -1607,6 +1607,7 @@ const (
        OpARM64FMOVDload
        OpARM64LDP
        OpARM64LDPW
+       OpARM64LDPSW
        OpARM64FLDPD
        OpARM64FLDPS
        OpARM64MOVDloadidx
@@ -21664,6 +21665,23 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:           "LDPSW",
+               auxType:        auxSymOff,
+               argLen:         2,
+               faultOnNilArg0: true,
+               symEffect:      SymRead,
+               asm:            arm64.ALDPSW,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB
+                       },
+                       outputs: []outputInfo{
+                               {0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                               {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+                       },
+               },
+       },
        {
                name:           "FLDPD",
                auxType:        auxSymOff,
index 5af9b0cb1b6d66f8f742d0e9d5a496718fff6535..8e022df036e5b27cd431a296aeefed9662c84163 100644 (file)
@@ -32,7 +32,10 @@ type pairableLoadInfo struct {
 // They must also take an offset in Aux/AuxInt.
 var pairableLoads = map[Op]pairableLoadInfo{
        OpARM64MOVDload:  {8, OpARM64LDP},
-       OpARM64MOVWload:  {4, OpARM64LDPW},
+       OpARM64MOVWUload: {4, OpARM64LDPW},
+       OpARM64MOVWload:  {4, OpARM64LDPSW},
+       // TODO: conceivably we could pair a signed and unsigned load
+       // if we knew the upper bits of one of them weren't being used.
        OpARM64FMOVDload: {8, OpARM64FLDPD},
        OpARM64FMOVSload: {4, OpARM64FLDPS},
 }
index 9345391b61928f3f0e70425f7909c6fc59c218f7..c5744bf8d7f1a2391619e04fdf03475ca3e36a5f 100644 (file)
@@ -982,6 +982,10 @@ func dwloadI64(p *struct{ a, b int64 }) int64 {
        return p.a + p.b
 }
 func dwloadI32(p *struct{ a, b int32 }) int32 {
+       // arm64:"LDPSW\t"
+       return p.a + p.b
+}
+func dwloadU32(p *struct{ a, b uint32 }) uint32 {
        // arm64:"LDPW\t"
        return p.a + p.b
 }
diff --git a/test/fixedbugs/issue71759.go b/test/fixedbugs/issue71759.go
new file mode 100644 (file)
index 0000000..8134ff0
--- /dev/null
@@ -0,0 +1,20 @@
+// run
+
+// Copyright 2025 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 main
+
+//go:noinline
+func f(p *[2]int32) (int64, int64) {
+       return int64(p[0]), int64(p[1])
+}
+
+func main() {
+       p := [2]int32{-1, -1}
+       x, y := f(&p)
+       if x != -1 || y != -1 {
+               println(x, y)
+       }
+}