Skip to content

Commit cc571da

Browse files
fengyoulinJorropo
authored andcommitted
cmd/compile: deduplicate instructions when rewrite func results
After CL 628075, do not rely on the memory arg of an OpLocalAddr. Fixes #74788 Change-Id: I4e893241e3949bb8f2d93c8b88cc102e155b725d Reviewed-on: https://go-review.googlesource.com/c/go/+/691275 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: David Chase <[email protected]> Reviewed-by: Jorropo <[email protected]> Reviewed-by: Mark Freeman <[email protected]>
1 parent 2174a79 commit cc571da

File tree

4 files changed

+46
-8
lines changed

4 files changed

+46
-8
lines changed

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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,8 @@ func (x *expandState) rewriteFuncResults(v *Value, b *Block, aux *AuxCall) {
243243
if len(aRegs) > 0 {
244244
result = &allResults
245245
} else {
246-
if a.Op == OpLoad && a.Args[0].Op == OpLocalAddr {
247-
addr := a.Args[0]
248-
if addr.MemoryArg() == a.MemoryArg() && addr.Aux == aux.NameOfResult(i) {
249-
continue // Self move to output parameter
250-
}
246+
if a.Op == OpLoad && a.Args[0].Op == OpLocalAddr && a.Args[0].Aux == aux.NameOfResult(i) {
247+
continue // Self move to output parameter
251248
}
252249
}
253250
rc.init(aRegs, aux.abiInfo, result, auxBase, auxOffset)

src/cmd/internal/testdir/testdir_test.go

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,9 +1462,10 @@ func (t test) wantedErrors(file, short string) (errs []wantedError) {
14621462

14631463
const (
14641464
// Regexp to match a single opcode check: optionally begin with "-" (to indicate
1465-
// a negative check), followed by a string literal enclosed in "" or ``. For "",
1465+
// a negative check) or a positive number (to specify the expected number of
1466+
// matches), followed by a string literal enclosed in "" or ``. For "",
14661467
// backslashes must be handled.
1467-
reMatchCheck = `-?(?:\x60[^\x60]*\x60|"(?:[^"\\]|\\.)*")`
1468+
reMatchCheck = `(-|[1-9]\d*)?(?:\x60[^\x60]*\x60|"(?:[^"\\]|\\.)*")`
14681469
)
14691470

14701471
var (
@@ -1516,6 +1517,8 @@ type wantedAsmOpcode struct {
15161517
fileline string // original source file/line (eg: "/path/foo.go:45")
15171518
line int // original source line
15181519
opcode *regexp.Regexp // opcode check to be performed on assembly output
1520+
expected int // expected number of matches
1521+
actual int // actual number that matched
15191522
negative bool // true if the check is supposed to fail rather than pass
15201523
found bool // true if the opcode check matched at least one in the output
15211524
}
@@ -1622,9 +1625,16 @@ func (t test) wantedAsmOpcodes(fn string) asmChecks {
16221625

16231626
for _, m := range rxAsmCheck.FindAllString(allchecks, -1) {
16241627
negative := false
1628+
expected := 0
16251629
if m[0] == '-' {
16261630
negative = true
16271631
m = m[1:]
1632+
} else if '1' <= m[0] && m[0] <= '9' {
1633+
for '0' <= m[0] && m[0] <= '9' {
1634+
expected *= 10
1635+
expected += int(m[0] - '0')
1636+
m = m[1:]
1637+
}
16281638
}
16291639

16301640
rxsrc, err := strconv.Unquote(m)
@@ -1650,6 +1660,7 @@ func (t test) wantedAsmOpcodes(fn string) asmChecks {
16501660
ops[env] = make(map[string][]wantedAsmOpcode)
16511661
}
16521662
ops[env][lnum] = append(ops[env][lnum], wantedAsmOpcode{
1663+
expected: expected,
16531664
negative: negative,
16541665
fileline: lnum,
16551666
line: i + 1,
@@ -1698,7 +1709,8 @@ func (t test) asmCheck(outStr string, fn string, env buildEnv, fullops map[strin
16981709
// run the checks.
16991710
if ops, found := fullops[srcFileLine]; found {
17001711
for i := range ops {
1701-
if !ops[i].found && ops[i].opcode.FindString(asm) != "" {
1712+
if (!ops[i].found || ops[i].expected > 0) && ops[i].opcode.FindString(asm) != "" {
1713+
ops[i].actual++
17021714
ops[i].found = true
17031715
}
17041716
}
@@ -1714,6 +1726,9 @@ func (t test) asmCheck(outStr string, fn string, env buildEnv, fullops map[strin
17141726
if o.negative == o.found {
17151727
failed = append(failed, o)
17161728
}
1729+
if o.expected > 0 && o.expected != o.actual {
1730+
failed = append(failed, o)
1731+
}
17171732
}
17181733
}
17191734
if len(failed) == 0 {
@@ -1737,6 +1752,8 @@ func (t test) asmCheck(outStr string, fn string, env buildEnv, fullops map[strin
17371752

17381753
if o.negative {
17391754
fmt.Fprintf(&errbuf, "%s:%d: %s: wrong opcode found: %q\n", t.goFileName(), o.line, env, o.opcode.String())
1755+
} else if o.expected > 0 {
1756+
fmt.Fprintf(&errbuf, "%s:%d: %s: wrong number of opcodes: %q\n", t.goFileName(), o.line, env, o.opcode.String())
17401757
} else {
17411758
fmt.Fprintf(&errbuf, "%s:%d: %s: opcode not found: %q\n", t.goFileName(), o.line, env, o.opcode.String())
17421759
}

test/codegen/README

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ For example:
9898
verifies that NO memmove call is present in the assembly generated for
9999
the copy() line.
100100

101+
The expected number of matches for the regexp can be specified using a
102+
positive number:
103+
104+
func fb(a [4]int) (r [4]int) {
105+
// amd64:2`MOVUPS[^,]+, X0$`,2`MOVUPS\sX0,[^\n]+$`
106+
return a
107+
}
101108

102109
- Architecture specifiers
103110

test/codegen/issue74788.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// asmcheck
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 codegen
8+
9+
func fa(a [2]int) (r [2]int) {
10+
// amd64:1`MOVUPS[^,]+, X0$`,1`MOVUPS\sX0,[^\n]+$`
11+
return a
12+
}
13+
14+
func fb(a [4]int) (r [4]int) {
15+
// amd64:2`MOVUPS[^,]+, X0$`,2`MOVUPS\sX0,[^\n]+$`
16+
return a
17+
}

0 commit comments

Comments
 (0)