cmd/compile,math: improve code generation for math.Abs

Implement int reg <-> fp reg moves on amd64.
If we see a load to int reg followed by an int->fp move, then we can just
load to the fp reg instead.  Same for stores.

math.Abs is now:

MOVQ	"".x+8(SP), AX
SHLQ	$1, AX
SHRQ	$1, AX
MOVQ	AX, "".~r1+16(SP)

math.Copysign is now:

MOVQ	"".x+8(SP), AX
SHLQ	$1, AX
SHRQ	$1, AX
MOVQ	"".y+16(SP), CX
SHRQ	$63, CX
SHLQ	$63, CX
ORQ	CX, AX
MOVQ	AX, "".~r2+24(SP)

math.Float64bits is now:

MOVSD	"".x+8(SP), X0
MOVSD	X0, "".~r1+16(SP)
(it would be nicer to use a non-SSE reg for this, nothing is perfect)

And due to the fix for #21440, the inlined version of these improve as well.

name      old time/op  new time/op  delta
Abs       1.38ns ± 5%  0.89ns ±10%  -35.54%  (p=0.000 n=10+10)
Copysign  1.56ns ± 7%  1.35ns ± 6%  -13.77%  (p=0.000 n=9+10)

Fixes #13095

Change-Id: Ibd7f2792412a6668608780b0688a77062e1f1499
Reviewed-on: https://go-review.googlesource.com/58732
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Ilya Tocar <ilya.tocar@intel.com>
This commit is contained in:
Keith Randall 2017-08-24 13:19:40 -07:00
parent e11fd00629
commit fb05948d9e
7 changed files with 1186 additions and 11 deletions

View file

@ -214,7 +214,7 @@ var allAsmTests = []*asmTests{
{
arch: "amd64",
os: "linux",
imports: []string{"encoding/binary", "math/bits", "unsafe"},
imports: []string{"encoding/binary", "math", "math/bits", "unsafe"},
tests: linuxAMD64Tests,
},
{
@ -990,6 +990,57 @@ var linuxAMD64Tests = []*asmTest{
`,
[]string{"TEXT\t.*, [$]0-8"},
},
// math.Abs using integer registers
{
`
func $(x float64) float64 {
return math.Abs(x)
}
`,
[]string{"\tSHLQ\t[$]1,", "\tSHRQ\t[$]1,"},
},
// math.Copysign using integer registers
{
`
func $(x, y float64) float64 {
return math.Copysign(x, y)
}
`,
[]string{"\tSHLQ\t[$]1,", "\tSHRQ\t[$]1,", "\tSHRQ\t[$]63,", "\tSHLQ\t[$]63,", "\tORQ\t"},
},
// int <-> fp moves
{
`
func $(x float64) uint64 {
return math.Float64bits(x+1) + 1
}
`,
[]string{"\tMOVQ\tX.*, [^X].*"},
},
{
`
func $(x float32) uint32 {
return math.Float32bits(x+1) + 1
}
`,
[]string{"\tMOVL\tX.*, [^X].*"},
},
{
`
func $(x uint64) float64 {
return math.Float64frombits(x+1) + 1
}
`,
[]string{"\tMOVQ\t[^X].*, X.*"},
},
{
`
func $(x uint32) float32 {
return math.Float32frombits(x+1) + 1
}
`,
[]string{"\tMOVL\t[^X].*, X.*"},
},
}
var linux386Tests = []*asmTest{