mirror of
https://github.com/golang/go
synced 2024-11-05 18:36:08 +00:00
runtime: teach peephole optimizer that duffcopy clobbers X0
Duffcopy now uses X0, as of 5cf281a
. Teach the peephole
optimizer that duffcopy clobbers X0 so that it does not
rename registers use X0 across the duffcopy instruction.
Fixes #13171
Change-Id: I389cbf1982cb6eb2f51e6152ac96736a8589f085
Reviewed-on: https://go-review.googlesource.com/16715
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Minux Ma <minux@golang.org>
Reviewed-by: Ilya Tocar <ilya.tocar@intel.com>
This commit is contained in:
parent
59bac0be90
commit
ffb20631fc
4 changed files with 40 additions and 1 deletions
|
@ -823,6 +823,10 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
|
|||
return 2
|
||||
}
|
||||
|
||||
if (p.Info.Reguse|p.Info.Regset)&FtoB(int(v.Reg)) != 0 {
|
||||
return 2
|
||||
}
|
||||
|
||||
if p.Info.Flags&gc.LeftAddr != 0 {
|
||||
if copyas(&p.From, v) {
|
||||
return 2
|
||||
|
|
|
@ -140,7 +140,7 @@ var progtable = [x86.ALAST]obj.ProgInfo{
|
|||
x86.AMOVSL: {Flags: gc.OK, Reguse: DI | SI, Regset: DI | SI},
|
||||
x86.AMOVSQ: {Flags: gc.OK, Reguse: DI | SI, Regset: DI | SI},
|
||||
x86.AMOVSW: {Flags: gc.OK, Reguse: DI | SI, Regset: DI | SI},
|
||||
obj.ADUFFCOPY: {Flags: gc.OK, Reguse: DI | SI, Regset: DI | SI | CX},
|
||||
obj.ADUFFCOPY: {Flags: gc.OK, Reguse: DI | SI, Regset: DI | SI | X0},
|
||||
x86.AMOVSD: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Move},
|
||||
x86.AMOVSS: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Move},
|
||||
|
||||
|
|
|
@ -107,6 +107,7 @@ const (
|
|||
DI = 1 << (x86.REG_DI - x86.REG_AX)
|
||||
SI = 1 << (x86.REG_SI - x86.REG_AX)
|
||||
R15 = 1 << (x86.REG_R15 - x86.REG_AX)
|
||||
X0 = 1 << 16
|
||||
)
|
||||
|
||||
func RtoB(r int) uint64 {
|
||||
|
|
34
test/fixedbugs/issue13171.go
Normal file
34
test/fixedbugs/issue13171.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
// run
|
||||
|
||||
// Copyright 2015 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
|
||||
|
||||
// Make sure the compiler knows that DUFFCOPY clobbers X0
|
||||
|
||||
import "fmt"
|
||||
|
||||
//go:noinline
|
||||
func f(x float64) float64 {
|
||||
// y is allocated to X0
|
||||
y := x + 5
|
||||
// marshals z before y. Marshalling z
|
||||
// calls DUFFCOPY.
|
||||
return g(z, y)
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func g(b [64]byte, y float64) float64 {
|
||||
return y
|
||||
}
|
||||
|
||||
var z [64]byte
|
||||
|
||||
func main() {
|
||||
got := f(5)
|
||||
if got != 10 {
|
||||
panic(fmt.Sprintf("want 10, got %f", got))
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue