Commit ffb20631 authored by Keith Randall's avatar Keith Randall

runtime: teach peephole optimizer that duffcopy clobbers X0

Duffcopy now uses X0, as of 5cf281a9.  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: 's avatarMinux Ma <minux@golang.org>
Reviewed-by: 's avatarIlya Tocar <ilya.tocar@intel.com>
parent 59bac0be
......@@ -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 {
......
// 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))
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment