cmd/compile: propagate constants through math.Float{32,64}{,from}bits

This CL adds generic SSA rules to propagate constants through raw bits
conversions between floats and integers. This allows constants to
propagate through some math functions. For example, math.Copysign(0, -1)
is now constant folded to a load of -0.0.

Requires a fix to the ARM assembler which loaded -0.0 as +0.0.

Change-Id: I52649a4691077c7414f19d17bb599a6743c23ac2
Reviewed-on: https://go-review.googlesource.com/62250
Run-TryBot: Michael Munday <mike.munday@ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Michael Munday 2017-09-08 01:31:13 +01:00
parent 4439b21d0c
commit 9da29b687f
5 changed files with 181 additions and 8 deletions

View file

@ -236,7 +236,7 @@ var allAsmTests = []*asmTests{
{
arch: "s390x",
os: "linux",
imports: []string{"encoding/binary", "math/bits"},
imports: []string{"encoding/binary", "math", "math/bits"},
tests: linuxS390XTests,
},
{
@ -263,9 +263,10 @@ var allAsmTests = []*asmTests{
tests: linuxMIPS64Tests,
},
{
arch: "ppc64le",
os: "linux",
tests: linuxPPC64LETests,
arch: "ppc64le",
os: "linux",
imports: []string{"math"},
tests: linuxPPC64LETests,
},
{
arch: "amd64",
@ -1466,6 +1467,31 @@ var linuxS390XTests = []*asmTest{
`,
pos: []string{"TEXT\t.*, [$]0-8"},
},
// Constant propagation through raw bits conversions.
{
// uint32 constant converted to float32 constant
fn: `
func $(x float32) float32 {
if x > math.Float32frombits(0x3f800000) {
return -x
}
return x
}
`,
pos: []string{"\tFMOVS\t[$]f32.3f800000\\(SB\\)"},
},
{
// float32 constant converted to uint32 constant
fn: `
func $(x uint32) uint32 {
if x > math.Float32bits(1) {
return -x
}
return x
}
`,
neg: []string{"\tFMOVS\t"},
},
}
var linuxARMTests = []*asmTest{
@ -1988,6 +2014,31 @@ var linuxPPC64LETests = []*asmTest{
`,
pos: []string{"TEXT\t.*, [$]0-8"},
},
// Constant propagation through raw bits conversions.
{
// uint32 constant converted to float32 constant
fn: `
func $(x float32) float32 {
if x > math.Float32frombits(0x3f800000) {
return -x
}
return x
}
`,
pos: []string{"\tFMOVS\t[$]f32.3f800000\\(SB\\)"},
},
{
// float32 constant converted to uint32 constant
fn: `
func $(x uint32) uint32 {
if x > math.Float32bits(1) {
return -x
}
return x
}
`,
neg: []string{"\tFMOVS\t"},
},
}
var plan9AMD64Tests = []*asmTest{