mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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 <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Jorropo <jorropo.pgm@gmail.com> Reviewed-by: Mark Freeman <mark@golang.org>
This commit is contained in:
parent
2174a7936c
commit
cc571dab91
4 changed files with 46 additions and 8 deletions
|
|
@ -243,11 +243,8 @@ func (x *expandState) rewriteFuncResults(v *Value, b *Block, aux *AuxCall) {
|
|||
if len(aRegs) > 0 {
|
||||
result = &allResults
|
||||
} else {
|
||||
if a.Op == OpLoad && a.Args[0].Op == OpLocalAddr {
|
||||
addr := a.Args[0]
|
||||
if addr.MemoryArg() == a.MemoryArg() && addr.Aux == aux.NameOfResult(i) {
|
||||
continue // Self move to output parameter
|
||||
}
|
||||
if a.Op == OpLoad && a.Args[0].Op == OpLocalAddr && a.Args[0].Aux == aux.NameOfResult(i) {
|
||||
continue // Self move to output parameter
|
||||
}
|
||||
}
|
||||
rc.init(aRegs, aux.abiInfo, result, auxBase, auxOffset)
|
||||
|
|
|
|||
|
|
@ -1462,9 +1462,10 @@ func (t test) wantedErrors(file, short string) (errs []wantedError) {
|
|||
|
||||
const (
|
||||
// Regexp to match a single opcode check: optionally begin with "-" (to indicate
|
||||
// a negative check), followed by a string literal enclosed in "" or ``. For "",
|
||||
// a negative check) or a positive number (to specify the expected number of
|
||||
// matches), followed by a string literal enclosed in "" or ``. For "",
|
||||
// backslashes must be handled.
|
||||
reMatchCheck = `-?(?:\x60[^\x60]*\x60|"(?:[^"\\]|\\.)*")`
|
||||
reMatchCheck = `(-|[1-9]\d*)?(?:\x60[^\x60]*\x60|"(?:[^"\\]|\\.)*")`
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -1516,6 +1517,8 @@ type wantedAsmOpcode struct {
|
|||
fileline string // original source file/line (eg: "/path/foo.go:45")
|
||||
line int // original source line
|
||||
opcode *regexp.Regexp // opcode check to be performed on assembly output
|
||||
expected int // expected number of matches
|
||||
actual int // actual number that matched
|
||||
negative bool // true if the check is supposed to fail rather than pass
|
||||
found bool // true if the opcode check matched at least one in the output
|
||||
}
|
||||
|
|
@ -1622,9 +1625,16 @@ func (t test) wantedAsmOpcodes(fn string) asmChecks {
|
|||
|
||||
for _, m := range rxAsmCheck.FindAllString(allchecks, -1) {
|
||||
negative := false
|
||||
expected := 0
|
||||
if m[0] == '-' {
|
||||
negative = true
|
||||
m = m[1:]
|
||||
} else if '1' <= m[0] && m[0] <= '9' {
|
||||
for '0' <= m[0] && m[0] <= '9' {
|
||||
expected *= 10
|
||||
expected += int(m[0] - '0')
|
||||
m = m[1:]
|
||||
}
|
||||
}
|
||||
|
||||
rxsrc, err := strconv.Unquote(m)
|
||||
|
|
@ -1650,6 +1660,7 @@ func (t test) wantedAsmOpcodes(fn string) asmChecks {
|
|||
ops[env] = make(map[string][]wantedAsmOpcode)
|
||||
}
|
||||
ops[env][lnum] = append(ops[env][lnum], wantedAsmOpcode{
|
||||
expected: expected,
|
||||
negative: negative,
|
||||
fileline: lnum,
|
||||
line: i + 1,
|
||||
|
|
@ -1698,7 +1709,8 @@ func (t test) asmCheck(outStr string, fn string, env buildEnv, fullops map[strin
|
|||
// run the checks.
|
||||
if ops, found := fullops[srcFileLine]; found {
|
||||
for i := range ops {
|
||||
if !ops[i].found && ops[i].opcode.FindString(asm) != "" {
|
||||
if (!ops[i].found || ops[i].expected > 0) && ops[i].opcode.FindString(asm) != "" {
|
||||
ops[i].actual++
|
||||
ops[i].found = true
|
||||
}
|
||||
}
|
||||
|
|
@ -1714,6 +1726,9 @@ func (t test) asmCheck(outStr string, fn string, env buildEnv, fullops map[strin
|
|||
if o.negative == o.found {
|
||||
failed = append(failed, o)
|
||||
}
|
||||
if o.expected > 0 && o.expected != o.actual {
|
||||
failed = append(failed, o)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(failed) == 0 {
|
||||
|
|
@ -1737,6 +1752,8 @@ func (t test) asmCheck(outStr string, fn string, env buildEnv, fullops map[strin
|
|||
|
||||
if o.negative {
|
||||
fmt.Fprintf(&errbuf, "%s:%d: %s: wrong opcode found: %q\n", t.goFileName(), o.line, env, o.opcode.String())
|
||||
} else if o.expected > 0 {
|
||||
fmt.Fprintf(&errbuf, "%s:%d: %s: wrong number of opcodes: %q\n", t.goFileName(), o.line, env, o.opcode.String())
|
||||
} else {
|
||||
fmt.Fprintf(&errbuf, "%s:%d: %s: opcode not found: %q\n", t.goFileName(), o.line, env, o.opcode.String())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,6 +98,13 @@ For example:
|
|||
verifies that NO memmove call is present in the assembly generated for
|
||||
the copy() line.
|
||||
|
||||
The expected number of matches for the regexp can be specified using a
|
||||
positive number:
|
||||
|
||||
func fb(a [4]int) (r [4]int) {
|
||||
// amd64:2`MOVUPS[^,]+, X0$`,2`MOVUPS\sX0,[^\n]+$`
|
||||
return a
|
||||
}
|
||||
|
||||
- Architecture specifiers
|
||||
|
||||
|
|
|
|||
17
test/codegen/issue74788.go
Normal file
17
test/codegen/issue74788.go
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// asmcheck
|
||||
|
||||
// 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 codegen
|
||||
|
||||
func fa(a [2]int) (r [2]int) {
|
||||
// amd64:1`MOVUPS[^,]+, X0$`,1`MOVUPS\sX0,[^\n]+$`
|
||||
return a
|
||||
}
|
||||
|
||||
func fb(a [4]int) (r [4]int) {
|
||||
// amd64:2`MOVUPS[^,]+, X0$`,2`MOVUPS\sX0,[^\n]+$`
|
||||
return a
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue