cmd/asm, cmd/compile: optimize math.Abs and math.Copysign on s390x

This change adds three new instructions:

- LPDFR: load positive (math.Abs(x))
- LNDFR: load negative (-math.Abs(x))
- CPSDR: copy sign (math.Copysign(x, y))

By making use of GPR <-> FPR moves we can now compile math.Abs and
math.Copysign to these instructions using SSA rules.

This CL also adds new rules to merge address generation into combined
load operations. This makes GPR <-> FPR move matching more reliable.

name                 old time/op  new time/op  delta
Copysign             1.85ns ± 0%  1.40ns ± 1%  -24.65%  (p=0.000 n=8+10)
Abs                  1.58ns ± 1%  0.73ns ± 1%  -53.64%  (p=0.000 n=10+10)

The geo mean improvement for all math package benchmarks was 4.6%.

Change-Id: I0cec35c5c1b3fb45243bf666b56b57faca981bc9
Reviewed-on: https://go-review.googlesource.com/73950
Run-TryBot: Michael Munday <mike.munday@ibm.com>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Michael Munday 2017-10-27 09:45:45 -04:00
parent 7fff1db060
commit 96cdacb971
10 changed files with 2035 additions and 134 deletions

View file

@ -1691,6 +1691,70 @@ var linuxS390XTests = []*asmTest{
pos: []string{"\tMOV(B|BZ|D)\t[$]1,"},
neg: []string{"\tCEBR\t", "\tMOV(B|BZ|D)\t[$]0,"},
},
// math tests
{
fn: `
func $(x float64) float64 {
return math.Abs(x)
}
`,
pos: []string{"\tLPDFR\t"},
neg: []string{"\tMOVD\t"}, // no integer loads/stores
},
{
fn: `
func $(x float32) float32 {
return float32(math.Abs(float64(x)))
}
`,
pos: []string{"\tLPDFR\t"},
neg: []string{"\tLDEBR\t", "\tLEDBR\t"}, // no float64 conversion
},
{
fn: `
func $(x float64) float64 {
return math.Float64frombits(math.Float64bits(x)|1<<63)
}
`,
pos: []string{"\tLNDFR\t"},
neg: []string{"\tMOVD\t"}, // no integer loads/stores
},
{
fn: `
func $(x float64) float64 {
return -math.Abs(x)
}
`,
pos: []string{"\tLNDFR\t"},
neg: []string{"\tMOVD\t"}, // no integer loads/stores
},
{
fn: `
func $(x, y float64) float64 {
return math.Copysign(x, y)
}
`,
pos: []string{"\tCPSDR\t"},
neg: []string{"\tMOVD\t"}, // no integer loads/stores
},
{
fn: `
func $(x float64) float64 {
return math.Copysign(x, -1)
}
`,
pos: []string{"\tLNDFR\t"},
neg: []string{"\tMOVD\t"}, // no integer loads/stores
},
{
fn: `
func $(x float64) float64 {
return math.Copysign(-1, x)
}
`,
pos: []string{"\tCPSDR\t"},
neg: []string{"\tMOVD\t"}, // no integer loads/stores
},
}
var linuxARMTests = []*asmTest{