Skip to content

Commit beac2f7

Browse files
committed
cmd/compile: fix sign extension of paired 32-bit loads on arm64
Fixes #71759 Change-Id: Iab05294ac933cc9972949158d3fe2bdc3073df5e Reviewed-on: https://go-review.googlesource.com/c/go/+/649895 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Cherry Mui <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
1 parent c62c69d commit beac2f7

File tree

6 files changed

+49
-3
lines changed

6 files changed

+49
-3
lines changed

src/cmd/compile/internal/arm64/ssa.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
516516
ssagen.AddAux(&p.From, v)
517517
p.To.Type = obj.TYPE_REG
518518
p.To.Reg = v.Reg()
519-
case ssa.OpARM64LDP, ssa.OpARM64LDPW, ssa.OpARM64FLDPD, ssa.OpARM64FLDPS:
519+
case ssa.OpARM64LDP, ssa.OpARM64LDPW, ssa.OpARM64LDPSW, ssa.OpARM64FLDPD, ssa.OpARM64FLDPS:
520520
p := s.Prog(v.Op.Asm())
521521
p.From.Type = obj.TYPE_MEM
522522
p.From.Reg = v.Args[0].Reg()

src/cmd/compile/internal/ssa/_gen/ARM64Ops.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,8 @@ func init() {
388388
// arg1=mem
389389
// Returns the tuple <x,y>.
390390
{name: "LDP", argLength: 2, reg: gpload2, aux: "SymOff", asm: "LDP", typ: "(UInt64,UInt64)", faultOnNilArg0: true, symEffect: "Read"}, // T=int64 (gp reg destination)
391-
{name: "LDPW", argLength: 2, reg: gpload2, aux: "SymOff", asm: "LDPW", typ: "(UInt32,UInt32)", faultOnNilArg0: true, symEffect: "Read"}, // T=int32 (gp reg destination) ??? extension
391+
{name: "LDPW", argLength: 2, reg: gpload2, aux: "SymOff", asm: "LDPW", typ: "(UInt32,UInt32)", faultOnNilArg0: true, symEffect: "Read"}, // T=int32 (gp reg destination) unsigned extension
392+
{name: "LDPSW", argLength: 2, reg: gpload2, aux: "SymOff", asm: "LDPSW", typ: "(Int32,Int32)", faultOnNilArg0: true, symEffect: "Read"}, // T=int32 (gp reg destination) signed extension
392393
{name: "FLDPD", argLength: 2, reg: fpload2, aux: "SymOff", asm: "FLDPD", typ: "(Float64,Float64)", faultOnNilArg0: true, symEffect: "Read"}, // T=float64 (fp reg destination)
393394
{name: "FLDPS", argLength: 2, reg: fpload2, aux: "SymOff", asm: "FLDPS", typ: "(Float32,Float32)", faultOnNilArg0: true, symEffect: "Read"}, // T=float32 (fp reg destination)
394395

src/cmd/compile/internal/ssa/opGen.go

+18
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/compile/internal/ssa/pair.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ type pairableLoadInfo struct {
3232
// They must also take an offset in Aux/AuxInt.
3333
var pairableLoads = map[Op]pairableLoadInfo{
3434
OpARM64MOVDload: {8, OpARM64LDP},
35-
OpARM64MOVWload: {4, OpARM64LDPW},
35+
OpARM64MOVWUload: {4, OpARM64LDPW},
36+
OpARM64MOVWload: {4, OpARM64LDPSW},
37+
// TODO: conceivably we could pair a signed and unsigned load
38+
// if we knew the upper bits of one of them weren't being used.
3639
OpARM64FMOVDload: {8, OpARM64FLDPD},
3740
OpARM64FMOVSload: {4, OpARM64FLDPS},
3841
}

test/codegen/memcombine.go

+4
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,10 @@ func dwloadI64(p *struct{ a, b int64 }) int64 {
982982
return p.a + p.b
983983
}
984984
func dwloadI32(p *struct{ a, b int32 }) int32 {
985+
// arm64:"LDPSW\t"
986+
return p.a + p.b
987+
}
988+
func dwloadU32(p *struct{ a, b uint32 }) uint32 {
985989
// arm64:"LDPW\t"
986990
return p.a + p.b
987991
}

test/fixedbugs/issue71759.go

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// run
2+
3+
// Copyright 2025 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 main
8+
9+
//go:noinline
10+
func f(p *[2]int32) (int64, int64) {
11+
return int64(p[0]), int64(p[1])
12+
}
13+
14+
func main() {
15+
p := [2]int32{-1, -1}
16+
x, y := f(&p)
17+
if x != -1 || y != -1 {
18+
println(x, y)
19+
}
20+
}

0 commit comments

Comments
 (0)