mirror of
https://github.com/golang/go
synced 2024-11-18 16:34:51 -07:00
cmd/compile: strength reduce more x86 constant multiplication
The additions were machine-generated. The change for x * 7 avoids a reg-reg move, reducing the number of instructions from 3 to 2. Change-Id: Ib002e39f29ca5e46cfdb8daaf87ddc7ba50a17e5 Reviewed-on: https://go-review.googlesource.com/102395 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
7bf631e1fc
commit
6a74fe2f15
2952
src/cmd/compile/internal/gc/testdata/arithConst.go
vendored
2952
src/cmd/compile/internal/gc/testdata/arithConst.go
vendored
File diff suppressed because it is too large
Load Diff
@ -28,16 +28,23 @@ type szD struct {
|
||||
sn string
|
||||
u []uint64
|
||||
i []int64
|
||||
oponly string
|
||||
}
|
||||
|
||||
var szs = []szD{
|
||||
{name: "uint64", sn: "64", u: []uint64{0, 1, 4294967296, 0x8000000000000000, 0xffffFFFFffffFFFF}},
|
||||
{name: "uint64", sn: "64", u: []uint64{3, 5, 7, 9, 10, 11, 13, 19, 21, 25, 27, 37, 41, 45, 73, 81}, oponly: "mul"},
|
||||
|
||||
{name: "int64", sn: "64", i: []int64{-0x8000000000000000, -0x7FFFFFFFFFFFFFFF,
|
||||
-4294967296, -1, 0, 1, 4294967296, 0x7FFFFFFFFFFFFFFE, 0x7FFFFFFFFFFFFFFF}},
|
||||
{name: "int64", sn: "64", i: []int64{-9, -5, -3, 3, 5, 7, 9, 10, 11, 13, 19, 21, 25, 27, 37, 41, 45, 73, 81}, oponly: "mul"},
|
||||
|
||||
{name: "uint32", sn: "32", u: []uint64{0, 1, 4294967295}},
|
||||
{name: "uint32", sn: "32", u: []uint64{3, 5, 7, 9, 10, 11, 13, 19, 21, 25, 27, 37, 41, 45, 73, 81}, oponly: "mul"},
|
||||
|
||||
{name: "int32", sn: "32", i: []int64{-0x80000000, -0x7FFFFFFF, -1, 0,
|
||||
1, 0x7FFFFFFF}},
|
||||
{name: "int32", sn: "32", i: []int64{-9, -5, -3, 3, 5, 7, 9, 10, 11, 13, 19, 21, 25, 27, 37, 41, 45, 73, 81}, oponly: "mul"},
|
||||
|
||||
{name: "uint16", sn: "16", u: []uint64{0, 1, 65535}},
|
||||
{name: "int16", sn: "16", i: []int64{-32768, -32767, -1, 0, 1, 32766, 32767}},
|
||||
@ -162,6 +169,9 @@ func {{.Name}}_{{.FNumber}}_{{.Type_}}(a {{.Type_}}) {{.Type_}} { return {{.Numb
|
||||
|
||||
for _, s := range szs {
|
||||
for _, o := range ops {
|
||||
if s.oponly != "" && s.oponly != o.name {
|
||||
continue
|
||||
}
|
||||
fd := fncData{o.name, s.name, o.symbol, "", ""}
|
||||
|
||||
// unsigned test cases
|
||||
@ -218,17 +228,20 @@ func {{.Name}}_{{.FNumber}}_{{.Type_}}(a {{.Type_}}) {{.Type_}} { return {{.Numb
|
||||
}
|
||||
for _, s := range szs {
|
||||
fmt.Fprintf(w, `
|
||||
type test_%[1]s struct {
|
||||
type test_%[1]s%[2]s struct {
|
||||
fn func (%[1]s) %[1]s
|
||||
fnname string
|
||||
in %[1]s
|
||||
want %[1]s
|
||||
}
|
||||
`, s.name)
|
||||
fmt.Fprintf(w, "var tests_%[1]s =[]test_%[1]s {\n\n", s.name)
|
||||
`, s.name, s.oponly)
|
||||
fmt.Fprintf(w, "var tests_%[1]s%[2]s =[]test_%[1]s {\n\n", s.name, s.oponly)
|
||||
|
||||
if len(s.u) > 0 {
|
||||
for _, o := range ops {
|
||||
if s.oponly != "" && s.oponly != o.name {
|
||||
continue
|
||||
}
|
||||
fd := cfncData{s.name, o.name, s.name, o.symbol, "", "", "", ""}
|
||||
for _, i := range s.u {
|
||||
fd.Number = fmt.Sprintf("%d", i)
|
||||
@ -262,6 +275,9 @@ type test_%[1]s struct {
|
||||
// signed
|
||||
if len(s.i) > 0 {
|
||||
for _, o := range ops {
|
||||
if s.oponly != "" && s.oponly != o.name {
|
||||
continue
|
||||
}
|
||||
// don't generate tests for shifts by signed integers
|
||||
if o.name == "lsh" || o.name == "rsh" {
|
||||
continue
|
||||
@ -303,7 +319,7 @@ func main() {
|
||||
`)
|
||||
|
||||
for _, s := range szs {
|
||||
fmt.Fprintf(w, `for _, test := range tests_%s {`, s.name)
|
||||
fmt.Fprintf(w, `for _, test := range tests_%s%s {`, s.name, s.oponly)
|
||||
// Use WriteString here to avoid a vet warning about formatting directives.
|
||||
w.WriteString(`if got := test.fn(test.in); got != test.want {
|
||||
fmt.Printf("%s(%d) = %d, want %d\n", test.fnname, test.in, got, test.want)
|
||||
|
@ -495,24 +495,34 @@
|
||||
|
||||
// strength reduction
|
||||
// Assumes that the following costs from https://gmplib.org/~tege/x86-timing.pdf:
|
||||
// 1 - addq, shlq, leaq, negq
|
||||
// 3 - imulq
|
||||
// 1 - addl, shll, leal, negl, subl
|
||||
// 3 - imull
|
||||
// This limits the rewrites to two instructions.
|
||||
// TODO: 27, 81
|
||||
// Note that negl always operates in-place,
|
||||
// which can require a register-register move
|
||||
// to preserve the original value,
|
||||
// so it must be used with care.
|
||||
(MULLconst [-9] x) -> (NEGL (LEAL8 <v.Type> x x))
|
||||
(MULLconst [-5] x) -> (NEGL (LEAL4 <v.Type> x x))
|
||||
(MULLconst [-3] x) -> (NEGL (LEAL2 <v.Type> x x))
|
||||
(MULLconst [-1] x) -> (NEGL x)
|
||||
(MULLconst [0] _) -> (MOVLconst [0])
|
||||
(MULLconst [1] x) -> x
|
||||
(MULLconst [3] x) -> (LEAL2 x x)
|
||||
(MULLconst [5] x) -> (LEAL4 x x)
|
||||
(MULLconst [7] x) -> (LEAL8 (NEGL <v.Type> x) x)
|
||||
(MULLconst [7] x) -> (LEAL2 x (LEAL2 <v.Type> x x))
|
||||
(MULLconst [9] x) -> (LEAL8 x x)
|
||||
(MULLconst [11] x) -> (LEAL2 x (LEAL4 <v.Type> x x))
|
||||
(MULLconst [13] x) -> (LEAL4 x (LEAL2 <v.Type> x x))
|
||||
(MULLconst [19] x) -> (LEAL2 x (LEAL8 <v.Type> x x))
|
||||
(MULLconst [21] x) -> (LEAL4 x (LEAL4 <v.Type> x x))
|
||||
(MULLconst [25] x) -> (LEAL8 x (LEAL2 <v.Type> x x))
|
||||
(MULLconst [27] x) -> (LEAL8 (LEAL2 <v.Type> x x) (LEAL2 <v.Type> x x))
|
||||
(MULLconst [37] x) -> (LEAL4 x (LEAL8 <v.Type> x x))
|
||||
(MULLconst [41] x) -> (LEAL8 x (LEAL4 <v.Type> x x))
|
||||
(MULLconst [45] x) -> (LEAL8 (LEAL4 <v.Type> x x) (LEAL4 <v.Type> x x))
|
||||
(MULLconst [73] x) -> (LEAL8 x (LEAL8 <v.Type> x x))
|
||||
(MULLconst [81] x) -> (LEAL8 (LEAL8 <v.Type> x x) (LEAL8 <v.Type> x x))
|
||||
|
||||
(MULLconst [c] x) && isPowerOfTwo(c+1) && c >= 15 -> (SUBL (SHLLconst <v.Type> [log2(c+1)] x) x)
|
||||
(MULLconst [c] x) && isPowerOfTwo(c-1) && c >= 17 -> (LEAL1 (SHLLconst <v.Type> [log2(c-1)] x) x)
|
||||
|
@ -954,24 +954,34 @@
|
||||
|
||||
// strength reduction
|
||||
// Assumes that the following costs from https://gmplib.org/~tege/x86-timing.pdf:
|
||||
// 1 - addq, shlq, leaq, negq
|
||||
// 1 - addq, shlq, leaq, negq, subq
|
||||
// 3 - imulq
|
||||
// This limits the rewrites to two instructions.
|
||||
// TODO: 27, 81
|
||||
// Note that negq always operates in-place,
|
||||
// which can require a register-register move
|
||||
// to preserve the original value,
|
||||
// so it must be used with care.
|
||||
(MULQconst [-9] x) -> (NEGQ (LEAQ8 <v.Type> x x))
|
||||
(MULQconst [-5] x) -> (NEGQ (LEAQ4 <v.Type> x x))
|
||||
(MULQconst [-3] x) -> (NEGQ (LEAQ2 <v.Type> x x))
|
||||
(MULQconst [-1] x) -> (NEGQ x)
|
||||
(MULQconst [0] _) -> (MOVQconst [0])
|
||||
(MULQconst [1] x) -> x
|
||||
(MULQconst [3] x) -> (LEAQ2 x x)
|
||||
(MULQconst [5] x) -> (LEAQ4 x x)
|
||||
(MULQconst [7] x) -> (LEAQ8 (NEGQ <v.Type> x) x)
|
||||
(MULQconst [7] x) -> (LEAQ2 x (LEAQ2 <v.Type> x x))
|
||||
(MULQconst [9] x) -> (LEAQ8 x x)
|
||||
(MULQconst [11] x) -> (LEAQ2 x (LEAQ4 <v.Type> x x))
|
||||
(MULQconst [13] x) -> (LEAQ4 x (LEAQ2 <v.Type> x x))
|
||||
(MULQconst [19] x) -> (LEAQ2 x (LEAQ8 <v.Type> x x))
|
||||
(MULQconst [21] x) -> (LEAQ4 x (LEAQ4 <v.Type> x x))
|
||||
(MULQconst [25] x) -> (LEAQ8 x (LEAQ2 <v.Type> x x))
|
||||
(MULQconst [27] x) -> (LEAQ8 (LEAQ2 <v.Type> x x) (LEAQ2 <v.Type> x x))
|
||||
(MULQconst [37] x) -> (LEAQ4 x (LEAQ8 <v.Type> x x))
|
||||
(MULQconst [41] x) -> (LEAQ8 x (LEAQ4 <v.Type> x x))
|
||||
(MULQconst [45] x) -> (LEAQ8 (LEAQ4 <v.Type> x x) (LEAQ4 <v.Type> x x))
|
||||
(MULQconst [73] x) -> (LEAQ8 x (LEAQ8 <v.Type> x x))
|
||||
(MULQconst [81] x) -> (LEAQ8 (LEAQ8 <v.Type> x x) (LEAQ8 <v.Type> x x))
|
||||
|
||||
(MULQconst [c] x) && isPowerOfTwo(c+1) && c >= 15 -> (SUBQ (SHLQconst <v.Type> [log2(c+1)] x) x)
|
||||
(MULQconst [c] x) && isPowerOfTwo(c-1) && c >= 17 -> (LEAQ1 (SHLQconst <v.Type> [log2(c-1)] x) x)
|
||||
|
@ -140,7 +140,7 @@ func rewriteValue386(v *Value) bool {
|
||||
case Op386MULL:
|
||||
return rewriteValue386_Op386MULL_0(v)
|
||||
case Op386MULLconst:
|
||||
return rewriteValue386_Op386MULLconst_0(v) || rewriteValue386_Op386MULLconst_10(v) || rewriteValue386_Op386MULLconst_20(v)
|
||||
return rewriteValue386_Op386MULLconst_0(v) || rewriteValue386_Op386MULLconst_10(v) || rewriteValue386_Op386MULLconst_20(v) || rewriteValue386_Op386MULLconst_30(v)
|
||||
case Op386NEGL:
|
||||
return rewriteValue386_Op386NEGL_0(v)
|
||||
case Op386NOTL:
|
||||
@ -8339,6 +8339,51 @@ func rewriteValue386_Op386MULLconst_0(v *Value) bool {
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MULLconst [-9] x)
|
||||
// cond:
|
||||
// result: (NEGL (LEAL8 <v.Type> x x))
|
||||
for {
|
||||
if v.AuxInt != -9 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
v.reset(Op386NEGL)
|
||||
v0 := b.NewValue0(v.Pos, Op386LEAL8, v.Type)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (MULLconst [-5] x)
|
||||
// cond:
|
||||
// result: (NEGL (LEAL4 <v.Type> x x))
|
||||
for {
|
||||
if v.AuxInt != -5 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
v.reset(Op386NEGL)
|
||||
v0 := b.NewValue0(v.Pos, Op386LEAL4, v.Type)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (MULLconst [-3] x)
|
||||
// cond:
|
||||
// result: (NEGL (LEAL2 <v.Type> x x))
|
||||
for {
|
||||
if v.AuxInt != -3 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
v.reset(Op386NEGL)
|
||||
v0 := b.NewValue0(v.Pos, Op386LEAL2, v.Type)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (MULLconst [-1] x)
|
||||
// cond:
|
||||
// result: (NEGL x)
|
||||
@ -8403,19 +8448,25 @@ func rewriteValue386_Op386MULLconst_0(v *Value) bool {
|
||||
}
|
||||
// match: (MULLconst [7] x)
|
||||
// cond:
|
||||
// result: (LEAL8 (NEGL <v.Type> x) x)
|
||||
// result: (LEAL2 x (LEAL2 <v.Type> x x))
|
||||
for {
|
||||
if v.AuxInt != 7 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
v.reset(Op386LEAL8)
|
||||
v0 := b.NewValue0(v.Pos, Op386NEGL, v.Type)
|
||||
v.reset(Op386LEAL2)
|
||||
v.AddArg(x)
|
||||
v0 := b.NewValue0(v.Pos, Op386LEAL2, v.Type)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValue386_Op386MULLconst_10(v *Value) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MULLconst [9] x)
|
||||
// cond:
|
||||
// result: (LEAL8 x x)
|
||||
@ -8461,11 +8512,22 @@ func rewriteValue386_Op386MULLconst_0(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
// match: (MULLconst [19] x)
|
||||
// cond:
|
||||
// result: (LEAL2 x (LEAL8 <v.Type> x x))
|
||||
for {
|
||||
if v.AuxInt != 19 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
v.reset(Op386LEAL2)
|
||||
v.AddArg(x)
|
||||
v0 := b.NewValue0(v.Pos, Op386LEAL8, v.Type)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
func rewriteValue386_Op386MULLconst_10(v *Value) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MULLconst [21] x)
|
||||
// cond:
|
||||
// result: (LEAL4 x (LEAL4 <v.Type> x x))
|
||||
@ -8498,6 +8560,25 @@ func rewriteValue386_Op386MULLconst_10(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (MULLconst [27] x)
|
||||
// cond:
|
||||
// result: (LEAL8 (LEAL2 <v.Type> x x) (LEAL2 <v.Type> x x))
|
||||
for {
|
||||
if v.AuxInt != 27 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
v.reset(Op386LEAL8)
|
||||
v0 := b.NewValue0(v.Pos, Op386LEAL2, v.Type)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Pos, Op386LEAL2, v.Type)
|
||||
v1.AddArg(x)
|
||||
v1.AddArg(x)
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
// match: (MULLconst [37] x)
|
||||
// cond:
|
||||
// result: (LEAL4 x (LEAL8 <v.Type> x x))
|
||||
@ -8530,6 +8611,30 @@ func rewriteValue386_Op386MULLconst_10(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (MULLconst [45] x)
|
||||
// cond:
|
||||
// result: (LEAL8 (LEAL4 <v.Type> x x) (LEAL4 <v.Type> x x))
|
||||
for {
|
||||
if v.AuxInt != 45 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
v.reset(Op386LEAL8)
|
||||
v0 := b.NewValue0(v.Pos, Op386LEAL4, v.Type)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Pos, Op386LEAL4, v.Type)
|
||||
v1.AddArg(x)
|
||||
v1.AddArg(x)
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValue386_Op386MULLconst_20(v *Value) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MULLconst [73] x)
|
||||
// cond:
|
||||
// result: (LEAL8 x (LEAL8 <v.Type> x x))
|
||||
@ -8546,6 +8651,25 @@ func rewriteValue386_Op386MULLconst_10(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (MULLconst [81] x)
|
||||
// cond:
|
||||
// result: (LEAL8 (LEAL8 <v.Type> x x) (LEAL8 <v.Type> x x))
|
||||
for {
|
||||
if v.AuxInt != 81 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
v.reset(Op386LEAL8)
|
||||
v0 := b.NewValue0(v.Pos, Op386LEAL8, v.Type)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Pos, Op386LEAL8, v.Type)
|
||||
v1.AddArg(x)
|
||||
v1.AddArg(x)
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
// match: (MULLconst [c] x)
|
||||
// cond: isPowerOfTwo(c+1) && c >= 15
|
||||
// result: (SUBL (SHLLconst <v.Type> [log2(c+1)] x) x)
|
||||
@ -8631,11 +8755,6 @@ func rewriteValue386_Op386MULLconst_10(v *Value) bool {
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValue386_Op386MULLconst_20(v *Value) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MULLconst [c] x)
|
||||
// cond: c%3 == 0 && isPowerOfTwo(c/3)
|
||||
// result: (SHLLconst [log2(c/3)] (LEAL2 <v.Type> x x))
|
||||
@ -8687,6 +8806,9 @@ func rewriteValue386_Op386MULLconst_20(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValue386_Op386MULLconst_30(v *Value) bool {
|
||||
// match: (MULLconst [c] (MOVLconst [d]))
|
||||
// cond:
|
||||
// result: (MOVLconst [int64(int32(c*d))])
|
||||
|
@ -300,7 +300,7 @@ func rewriteValueAMD64(v *Value) bool {
|
||||
case OpAMD64MULQ:
|
||||
return rewriteValueAMD64_OpAMD64MULQ_0(v)
|
||||
case OpAMD64MULQconst:
|
||||
return rewriteValueAMD64_OpAMD64MULQconst_0(v) || rewriteValueAMD64_OpAMD64MULQconst_10(v) || rewriteValueAMD64_OpAMD64MULQconst_20(v)
|
||||
return rewriteValueAMD64_OpAMD64MULQconst_0(v) || rewriteValueAMD64_OpAMD64MULQconst_10(v) || rewriteValueAMD64_OpAMD64MULQconst_20(v) || rewriteValueAMD64_OpAMD64MULQconst_30(v)
|
||||
case OpAMD64MULSD:
|
||||
return rewriteValueAMD64_OpAMD64MULSD_0(v)
|
||||
case OpAMD64MULSDmem:
|
||||
@ -19190,6 +19190,51 @@ func rewriteValueAMD64_OpAMD64MULQconst_0(v *Value) bool {
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MULQconst [-9] x)
|
||||
// cond:
|
||||
// result: (NEGQ (LEAQ8 <v.Type> x x))
|
||||
for {
|
||||
if v.AuxInt != -9 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
v.reset(OpAMD64NEGQ)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64LEAQ8, v.Type)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (MULQconst [-5] x)
|
||||
// cond:
|
||||
// result: (NEGQ (LEAQ4 <v.Type> x x))
|
||||
for {
|
||||
if v.AuxInt != -5 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
v.reset(OpAMD64NEGQ)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64LEAQ4, v.Type)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (MULQconst [-3] x)
|
||||
// cond:
|
||||
// result: (NEGQ (LEAQ2 <v.Type> x x))
|
||||
for {
|
||||
if v.AuxInt != -3 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
v.reset(OpAMD64NEGQ)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64LEAQ2, v.Type)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (MULQconst [-1] x)
|
||||
// cond:
|
||||
// result: (NEGQ x)
|
||||
@ -19254,19 +19299,25 @@ func rewriteValueAMD64_OpAMD64MULQconst_0(v *Value) bool {
|
||||
}
|
||||
// match: (MULQconst [7] x)
|
||||
// cond:
|
||||
// result: (LEAQ8 (NEGQ <v.Type> x) x)
|
||||
// result: (LEAQ2 x (LEAQ2 <v.Type> x x))
|
||||
for {
|
||||
if v.AuxInt != 7 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
v.reset(OpAMD64LEAQ8)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64NEGQ, v.Type)
|
||||
v.reset(OpAMD64LEAQ2)
|
||||
v.AddArg(x)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64LEAQ2, v.Type)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpAMD64MULQconst_10(v *Value) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MULQconst [9] x)
|
||||
// cond:
|
||||
// result: (LEAQ8 x x)
|
||||
@ -19312,11 +19363,22 @@ func rewriteValueAMD64_OpAMD64MULQconst_0(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
// match: (MULQconst [19] x)
|
||||
// cond:
|
||||
// result: (LEAQ2 x (LEAQ8 <v.Type> x x))
|
||||
for {
|
||||
if v.AuxInt != 19 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
v.reset(OpAMD64LEAQ2)
|
||||
v.AddArg(x)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64LEAQ8, v.Type)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
func rewriteValueAMD64_OpAMD64MULQconst_10(v *Value) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MULQconst [21] x)
|
||||
// cond:
|
||||
// result: (LEAQ4 x (LEAQ4 <v.Type> x x))
|
||||
@ -19349,6 +19411,25 @@ func rewriteValueAMD64_OpAMD64MULQconst_10(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (MULQconst [27] x)
|
||||
// cond:
|
||||
// result: (LEAQ8 (LEAQ2 <v.Type> x x) (LEAQ2 <v.Type> x x))
|
||||
for {
|
||||
if v.AuxInt != 27 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
v.reset(OpAMD64LEAQ8)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64LEAQ2, v.Type)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Pos, OpAMD64LEAQ2, v.Type)
|
||||
v1.AddArg(x)
|
||||
v1.AddArg(x)
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
// match: (MULQconst [37] x)
|
||||
// cond:
|
||||
// result: (LEAQ4 x (LEAQ8 <v.Type> x x))
|
||||
@ -19381,6 +19462,30 @@ func rewriteValueAMD64_OpAMD64MULQconst_10(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (MULQconst [45] x)
|
||||
// cond:
|
||||
// result: (LEAQ8 (LEAQ4 <v.Type> x x) (LEAQ4 <v.Type> x x))
|
||||
for {
|
||||
if v.AuxInt != 45 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
v.reset(OpAMD64LEAQ8)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64LEAQ4, v.Type)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Pos, OpAMD64LEAQ4, v.Type)
|
||||
v1.AddArg(x)
|
||||
v1.AddArg(x)
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpAMD64MULQconst_20(v *Value) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MULQconst [73] x)
|
||||
// cond:
|
||||
// result: (LEAQ8 x (LEAQ8 <v.Type> x x))
|
||||
@ -19397,6 +19502,25 @@ func rewriteValueAMD64_OpAMD64MULQconst_10(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (MULQconst [81] x)
|
||||
// cond:
|
||||
// result: (LEAQ8 (LEAQ8 <v.Type> x x) (LEAQ8 <v.Type> x x))
|
||||
for {
|
||||
if v.AuxInt != 81 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
v.reset(OpAMD64LEAQ8)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64LEAQ8, v.Type)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Pos, OpAMD64LEAQ8, v.Type)
|
||||
v1.AddArg(x)
|
||||
v1.AddArg(x)
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
// match: (MULQconst [c] x)
|
||||
// cond: isPowerOfTwo(c+1) && c >= 15
|
||||
// result: (SUBQ (SHLQconst <v.Type> [log2(c+1)] x) x)
|
||||
@ -19482,11 +19606,6 @@ func rewriteValueAMD64_OpAMD64MULQconst_10(v *Value) bool {
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpAMD64MULQconst_20(v *Value) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MULQconst [c] x)
|
||||
// cond: c%3 == 0 && isPowerOfTwo(c/3)
|
||||
// result: (SHLQconst [log2(c/3)] (LEAQ2 <v.Type> x x))
|
||||
@ -19538,6 +19657,9 @@ func rewriteValueAMD64_OpAMD64MULQconst_20(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpAMD64MULQconst_30(v *Value) bool {
|
||||
// match: (MULQconst [c] (MOVQconst [d]))
|
||||
// cond:
|
||||
// result: (MOVQconst [c*d])
|
||||
|
Loading…
Reference in New Issue
Block a user