mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: simplify negative on multiplication
goos: linux
goarch: amd64
pkg: cmd/compile/internal/test
cpu: AMD EPYC 7532 32-Core Processor
│ simplify_base │ simplify_new │
│ sec/op │ sec/op vs base │
SimplifyNegMul 623.0n ± 0% 319.3n ± 1% -48.75% (p=0.000 n=10)
goos: linux
goarch: riscv64
pkg: cmd/compile/internal/test
cpu: Spacemit(R) X60
│ simplify.base │ simplify.new │
│ sec/op │ sec/op vs base │
SimplifyNegMul 10.928µ ± 0% 6.432µ ± 0% -41.14% (p=0.000 n=10)
Change-Id: I1d9393cd19a0b948a5d3a512d627cdc0cf0b38be
Reviewed-on: https://go-review.googlesource.com/c/go/+/721520
Reviewed-by: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Mark Freeman <markfreeman@google.com>
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
35d2712b32
commit
e7d47ac33d
4 changed files with 228 additions and 0 deletions
|
|
@ -200,6 +200,10 @@
|
|||
|
||||
(Mul(8|16|32|64) (Neg(8|16|32|64) x) (Neg(8|16|32|64) y)) => (Mul(8|16|32|64) x y)
|
||||
|
||||
// simplify negative on mul if possible
|
||||
(Neg(8|16|32|64) (Mul(8|16|32|64) x (Const(8|16|32|64) <t> [c]))) => (Mul(8|16|32|64) x (Const(8|16|32|64) <t> [-c]))
|
||||
(Neg(8|16|32|64) (Mul(8|16|32|64) x (Neg(8|16|32|64) y))) => (Mul(8|16|32|64) x y)
|
||||
|
||||
// DeMorgan's Laws
|
||||
(And(8|16|32|64) <t> (Com(8|16|32|64) x) (Com(8|16|32|64) y)) => (Com(8|16|32|64) (Or(8|16|32|64) <t> x y))
|
||||
(Or(8|16|32|64) <t> (Com(8|16|32|64) x) (Com(8|16|32|64) y)) => (Com(8|16|32|64) (And(8|16|32|64) <t> x y))
|
||||
|
|
|
|||
|
|
@ -18069,6 +18069,51 @@ func rewriteValuegeneric_OpNeg16(v *Value) bool {
|
|||
v.AuxInt = int16ToAuxInt(-c)
|
||||
return true
|
||||
}
|
||||
// match: (Neg16 (Mul16 x (Const16 <t> [c])))
|
||||
// result: (Mul16 x (Const16 <t> [-c]))
|
||||
for {
|
||||
if v_0.Op != OpMul16 {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
x := v_0_0
|
||||
if v_0_1.Op != OpConst16 {
|
||||
continue
|
||||
}
|
||||
t := v_0_1.Type
|
||||
c := auxIntToInt16(v_0_1.AuxInt)
|
||||
v.reset(OpMul16)
|
||||
v0 := b.NewValue0(v.Pos, OpConst16, t)
|
||||
v0.AuxInt = int16ToAuxInt(-c)
|
||||
v.AddArg2(x, v0)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Neg16 (Mul16 x (Neg16 y)))
|
||||
// result: (Mul16 x y)
|
||||
for {
|
||||
if v_0.Op != OpMul16 {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
x := v_0_0
|
||||
if v_0_1.Op != OpNeg16 {
|
||||
continue
|
||||
}
|
||||
y := v_0_1.Args[0]
|
||||
v.reset(OpMul16)
|
||||
v.AddArg2(x, y)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Neg16 (Sub16 x y))
|
||||
// result: (Sub16 y x)
|
||||
for {
|
||||
|
|
@ -18121,6 +18166,51 @@ func rewriteValuegeneric_OpNeg32(v *Value) bool {
|
|||
v.AuxInt = int32ToAuxInt(-c)
|
||||
return true
|
||||
}
|
||||
// match: (Neg32 (Mul32 x (Const32 <t> [c])))
|
||||
// result: (Mul32 x (Const32 <t> [-c]))
|
||||
for {
|
||||
if v_0.Op != OpMul32 {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
x := v_0_0
|
||||
if v_0_1.Op != OpConst32 {
|
||||
continue
|
||||
}
|
||||
t := v_0_1.Type
|
||||
c := auxIntToInt32(v_0_1.AuxInt)
|
||||
v.reset(OpMul32)
|
||||
v0 := b.NewValue0(v.Pos, OpConst32, t)
|
||||
v0.AuxInt = int32ToAuxInt(-c)
|
||||
v.AddArg2(x, v0)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Neg32 (Mul32 x (Neg32 y)))
|
||||
// result: (Mul32 x y)
|
||||
for {
|
||||
if v_0.Op != OpMul32 {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
x := v_0_0
|
||||
if v_0_1.Op != OpNeg32 {
|
||||
continue
|
||||
}
|
||||
y := v_0_1.Args[0]
|
||||
v.reset(OpMul32)
|
||||
v.AddArg2(x, y)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Neg32 (Sub32 x y))
|
||||
// result: (Sub32 y x)
|
||||
for {
|
||||
|
|
@ -18192,6 +18282,51 @@ func rewriteValuegeneric_OpNeg64(v *Value) bool {
|
|||
v.AuxInt = int64ToAuxInt(-c)
|
||||
return true
|
||||
}
|
||||
// match: (Neg64 (Mul64 x (Const64 <t> [c])))
|
||||
// result: (Mul64 x (Const64 <t> [-c]))
|
||||
for {
|
||||
if v_0.Op != OpMul64 {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
x := v_0_0
|
||||
if v_0_1.Op != OpConst64 {
|
||||
continue
|
||||
}
|
||||
t := v_0_1.Type
|
||||
c := auxIntToInt64(v_0_1.AuxInt)
|
||||
v.reset(OpMul64)
|
||||
v0 := b.NewValue0(v.Pos, OpConst64, t)
|
||||
v0.AuxInt = int64ToAuxInt(-c)
|
||||
v.AddArg2(x, v0)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Neg64 (Mul64 x (Neg64 y)))
|
||||
// result: (Mul64 x y)
|
||||
for {
|
||||
if v_0.Op != OpMul64 {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
x := v_0_0
|
||||
if v_0_1.Op != OpNeg64 {
|
||||
continue
|
||||
}
|
||||
y := v_0_1.Args[0]
|
||||
v.reset(OpMul64)
|
||||
v.AddArg2(x, y)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Neg64 (Sub64 x y))
|
||||
// result: (Sub64 y x)
|
||||
for {
|
||||
|
|
@ -18263,6 +18398,51 @@ func rewriteValuegeneric_OpNeg8(v *Value) bool {
|
|||
v.AuxInt = int8ToAuxInt(-c)
|
||||
return true
|
||||
}
|
||||
// match: (Neg8 (Mul8 x (Const8 <t> [c])))
|
||||
// result: (Mul8 x (Const8 <t> [-c]))
|
||||
for {
|
||||
if v_0.Op != OpMul8 {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
x := v_0_0
|
||||
if v_0_1.Op != OpConst8 {
|
||||
continue
|
||||
}
|
||||
t := v_0_1.Type
|
||||
c := auxIntToInt8(v_0_1.AuxInt)
|
||||
v.reset(OpMul8)
|
||||
v0 := b.NewValue0(v.Pos, OpConst8, t)
|
||||
v0.AuxInt = int8ToAuxInt(-c)
|
||||
v.AddArg2(x, v0)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Neg8 (Mul8 x (Neg8 y)))
|
||||
// result: (Mul8 x y)
|
||||
for {
|
||||
if v_0.Op != OpMul8 {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
x := v_0_0
|
||||
if v_0_1.Op != OpNeg8 {
|
||||
continue
|
||||
}
|
||||
y := v_0_1.Args[0]
|
||||
v.reset(OpMul8)
|
||||
v.AddArg2(x, y)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Neg8 (Sub8 x y))
|
||||
// result: (Sub8 y x)
|
||||
for {
|
||||
|
|
|
|||
|
|
@ -145,3 +145,32 @@ func BenchmarkMul2Neg(b *testing.B) {
|
|||
globl = s
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSimplifyNegMul(b *testing.B) {
|
||||
x := make([]int64, 1024)
|
||||
y := make([]int64, 1024)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
var s int64
|
||||
for i := range x {
|
||||
s = -(-x[i] * y[i])
|
||||
}
|
||||
globl = s
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSimplifyNegDiv(b *testing.B) {
|
||||
x := make([]int64, 1024)
|
||||
y := make([]int64, 1024)
|
||||
for i := range y {
|
||||
y[i] = 42
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
var s int64
|
||||
for i := range x {
|
||||
s = -(-x[i] / y[i])
|
||||
}
|
||||
globl = s
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -337,11 +337,26 @@ func Mul32(a, b int32) int64 {
|
|||
// arm64:"SMULL" -"MOVW"
|
||||
return int64(a) * int64(b)
|
||||
}
|
||||
|
||||
func Mul32U(a, b uint32) uint64 {
|
||||
// arm64:"UMULL" -"MOVWU"
|
||||
return uint64(a) * uint64(b)
|
||||
}
|
||||
|
||||
func SimplifyNegMulConst(a int) int {
|
||||
// amd64:-"NEGQ"
|
||||
// arm64:"MOVD [$]11" "MUL" -"NEG"
|
||||
// riscv64:"MOV [$]11" "MUL" -"NEG"
|
||||
return -(a * -11)
|
||||
}
|
||||
|
||||
func SimplifyNegMul(a, b int) int {
|
||||
// amd64:-"NEGQ"
|
||||
// arm64:"MUL" -"NEG"
|
||||
// riscv64:"MUL" -"NEG"
|
||||
return -(-a * b)
|
||||
}
|
||||
|
||||
// -------------- //
|
||||
// Division //
|
||||
// -------------- //
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue