Commit fb165eaf authored by Cholerae Hu's avatar Cholerae Hu Committed by Keith Randall

cmd/compile: combine x*n - y*n into (x-y)*n

Do the similar thing to CL 55143 to reduce IMUL.

Change-Id: I1bd38f618058e3cd74fac181f003610ea13f2294
Reviewed-on: https://go-review.googlesource.com/56252
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarKeith Randall <khr@golang.org>
parent 03c3bb5f
......@@ -831,6 +831,20 @@ var linuxAMD64Tests = []*asmTest{
}`,
pos: []string{"\tADDQ\t[$]19", "\tIMULQ"}, // (a+19)*n
},
{
`
func mul4(n int) int {
return 23*n - 9*n
}`,
[]string{"\tIMULQ\t[$]14"}, // 14*n
},
{
`
func mul5(a, n int) int {
return a*n - 19*n
}`,
[]string{"\tADDQ\t[$]-19", "\tIMULQ"}, // (a-19)*n
},
// see issue 19595.
// We want to merge load+op in f58, but not in f59.
......@@ -1150,6 +1164,20 @@ var linux386Tests = []*asmTest{
`,
pos: []string{"TEXT\t.*, [$]0-4"},
},
{
`
func mul3(n int) int {
return 23*n - 9*n
}`,
[]string{"\tIMULL\t[$]14"}, // 14*n
},
{
`
func mul4(a, n int) int {
return n*a - a*19
}`,
[]string{"\tADDL\t[$]-19", "\tIMULL"}, // (n-19)*a
},
}
var linuxS390XTests = []*asmTest{
......
......@@ -328,6 +328,12 @@
(Add16 <t> (Mul16 x y) (Mul16 x z)) -> (Mul16 x (Add16 <t> y z))
(Add8 <t> (Mul8 x y) (Mul8 x z)) -> (Mul8 x (Add8 <t> y z))
// Rewrite x*y - x*z to x*(y-z)
(Sub64 <t> (Mul64 x y) (Mul64 x z)) -> (Mul64 x (Sub64 <t> y z))
(Sub32 <t> (Mul32 x y) (Mul32 x z)) -> (Mul32 x (Sub32 <t> y z))
(Sub16 <t> (Mul16 x y) (Mul16 x z)) -> (Mul16 x (Sub16 <t> y z))
(Sub8 <t> (Mul8 x y) (Mul8 x z)) -> (Mul8 x (Sub8 <t> y z))
// rewrite shifts of 8/16/32 bit consts into 64 bit consts to reduce
// the number of the other rewrite rules for const shifts
(Lsh64x32 <t> x (Const32 [c])) -> (Lsh64x64 x (Const64 <t> [int64(uint32(c))]))
......
......@@ -24,7 +24,7 @@ import "fmt"
// if a8 != b8 {
// // print error msg and panic
// }
func makeMergeTest(m1, m2, k int, size string) string {
func makeMergeAddTest(m1, m2, k int, size string) string {
model := " a" + size + ", b" + size
model += fmt.Sprintf(" = %%d*n%s + %%d*(n%s+%%d), (%%d+%%d)*n%s + (%%d*%%d)", size, size, size)
......@@ -32,7 +32,39 @@ func makeMergeTest(m1, m2, k int, size string) string {
test := fmt.Sprintf(model, m1, m2, k, m1, m2, m2, k)
test += fmt.Sprintf(`
if a%s != b%s {
fmt.Printf("MergeTest(%d, %d, %d, %s) failed\n")
fmt.Printf("MergeAddTest(%d, %d, %d, %s) failed\n")
fmt.Printf("%%d != %%d\n", a%s, b%s)
panic("FAIL")
}
`, size, size, m1, m2, k, size, size, size)
return test + "\n"
}
// Check that expressions like (c*n - d*(n+k)) get correctly merged by
// the compiler into (c-d)*n - d*k (with c-d and d*k computed at
// compile time).
//
// The merging is performed by a combination of the multiplication
// merge rules
// (c*n - d*n) -> (c-d)*n
// and the distributive multiplication rules
// c * (d-x) -> c*d - c*x
// Generate a MergeTest that looks like this:
//
// a8, b8 = m1*n8 - m2*(n8+k), (m1-m2)*n8 - m2*k
// if a8 != b8 {
// // print error msg and panic
// }
func makeMergeSubTest(m1, m2, k int, size string) string {
model := " a" + size + ", b" + size
model += fmt.Sprintf(" = %%d*n%s - %%d*(n%s+%%d), (%%d-%%d)*n%s - (%%d*%%d)", size, size, size)
test := fmt.Sprintf(model, m1, m2, k, m1, m2, m2, k)
test += fmt.Sprintf(`
if a%s != b%s {
fmt.Printf("MergeSubTest(%d, %d, %d, %s) failed\n")
fmt.Printf("%%d != %%d\n", a%s, b%s)
panic("FAIL")
}
......@@ -42,10 +74,14 @@ func makeMergeTest(m1, m2, k int, size string) string {
func makeAllSizes(m1, m2, k int) string {
var tests string
tests += makeMergeTest(m1, m2, k, "8")
tests += makeMergeTest(m1, m2, k, "16")
tests += makeMergeTest(m1, m2, k, "32")
tests += makeMergeTest(m1, m2, k, "64")
tests += makeMergeAddTest(m1, m2, k, "8")
tests += makeMergeAddTest(m1, m2, k, "16")
tests += makeMergeAddTest(m1, m2, k, "32")
tests += makeMergeAddTest(m1, m2, k, "64")
tests += makeMergeSubTest(m1, m2, k, "8")
tests += makeMergeSubTest(m1, m2, k, "16")
tests += makeMergeSubTest(m1, m2, k, "32")
tests += makeMergeSubTest(m1, m2, k, "64")
tests += "\n"
return tests
}
......
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