Skip to content

Commit 5a56d88

Browse files
randall77gopherbot
authored andcommitted
cmd/compile: ensure we use allowed registers for input-clobbering instructions
For instructions which clobber their input register, we make a second copy of the input value so it is still available in a register for future instructions. That second copy might not respect the register input restrictions for the instruction. So the second copy we make here can't actually be used by the instruction - it should use the first copy, the second copy is the one that will persist beyond the clobber. Fixes golang#75063 Change-Id: I99acdc63f0c4e54567a174ff7ada601ae4e796b7 Reviewed-on: https://go-review.googlesource.com/c/go/+/697015 Auto-Submit: Keith Randall <[email protected]> Reviewed-by: Keith Randall <[email protected]> Reviewed-by: David Chase <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent c3927a4 commit 5a56d88

File tree

2 files changed

+76
-2
lines changed

2 files changed

+76
-2
lines changed

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,10 +1725,9 @@ func (s *regAllocState) regalloc(f *Func) {
17251725
// spilling the value with the most distant next use.
17261726
continue
17271727
}
1728-
// Copy input to a new clobberable register.
1728+
// Copy input to a different register that won't be clobbered.
17291729
c := s.allocValToReg(v.Args[i], m, true, v.Pos)
17301730
s.copies[c] = false
1731-
args[i] = c
17321731
}
17331732

17341733
// Pick a temporary register if needed.

test/fixedbugs/issue75063.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// compile
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 reorder
8+
9+
type Element struct {
10+
A string
11+
B string
12+
C string
13+
D string
14+
E string
15+
Text []string
16+
List []string
17+
Child Elements
18+
F string
19+
G bool
20+
H bool
21+
I string
22+
}
23+
24+
type Elements []Element
25+
26+
func DoesNotCompile(ve Elements) Elements {
27+
aa := Elements{}
28+
bb := Elements{}
29+
cc := Elements{}
30+
dd := Elements{}
31+
ee := Elements{}
32+
ff := Elements{}
33+
gg := Elements{}
34+
hh := Elements{}
35+
ii := Elements{}
36+
37+
if len(ve) != 1 {
38+
return ve
39+
}
40+
for _, e := range ve[0].Child {
41+
if len(e.Text) == 1 && (e.Text[0] == "xx") {
42+
ee = append(ee, e)
43+
} else if len(e.Text) == 1 && e.Text[0] == "yy" {
44+
for _, c := range e.Child {
45+
if len(c.Text) == 1 && c.Text[0] == "zz" {
46+
ii = append(ii, c)
47+
} else {
48+
hh = append(hh, c)
49+
}
50+
}
51+
ii = append(ii, hh...)
52+
e.Child = ii
53+
gg = append(gg, e)
54+
} else if len(e.Text) == 1 && e.Text[0] == "tt" {
55+
for _, entry := range e.Child {
56+
for _, c := range entry.Child {
57+
if len(c.Text) == 1 && c.Text[0] == "ee" {
58+
cc = append(cc, c)
59+
} else {
60+
dd = append(dd, c)
61+
}
62+
}
63+
cc = append(cc, dd...)
64+
entry.Child = cc
65+
bb = append(bb, entry)
66+
cc, dd = Elements{}, Elements{}
67+
}
68+
e.Child = bb
69+
aa = append(aa, e)
70+
} else {
71+
ff = append(ff, e)
72+
}
73+
}
74+
return ve
75+
}

0 commit comments

Comments
 (0)