Commit 20046020 authored by Ben Shi's avatar Ben Shi Committed by Cherry Zhang

cmd/compile: fix an issue in MNEG of ARM64

There are two less optimized SSA rules in my previous CL
https://go-review.googlesource.com/c/go/+/95075 .

This CL fixes that issue and a test case gets about 10%
performance improvement.
name    old time/op  new time/op  delta
MNEG-4   263µs ± 3%   235µs ± 3%  -10.53%  (p=0.000 n=20+20)
(https://github.com/benshi001/ugo1/blob/master/mneg_7_test.go)

Change-Id: I30087097e281dd9d9d1c870d32e13b4ef4a96ad3
Reviewed-on: https://go-review.googlesource.com/99495
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
parent 0def0f2e
...@@ -862,9 +862,9 @@ ...@@ -862,9 +862,9 @@
(MNEG x (MOVDconst [c])) && isPowerOfTwo(c) -> (NEG (SLLconst <x.Type> [log2(c)] x)) (MNEG x (MOVDconst [c])) && isPowerOfTwo(c) -> (NEG (SLLconst <x.Type> [log2(c)] x))
(MNEG x (MOVDconst [c])) && isPowerOfTwo(c-1) && c >= 3 -> (NEG (ADDshiftLL <x.Type> x x [log2(c-1)])) (MNEG x (MOVDconst [c])) && isPowerOfTwo(c-1) && c >= 3 -> (NEG (ADDshiftLL <x.Type> x x [log2(c-1)]))
(MNEG x (MOVDconst [c])) && isPowerOfTwo(c+1) && c >= 7 -> (NEG (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log2(c+1)])) (MNEG x (MOVDconst [c])) && isPowerOfTwo(c+1) && c >= 7 -> (NEG (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log2(c+1)]))
(MNEG x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo(c/3) -> (NEG (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1]))) (MNEG x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo(c/3) -> (SLLconst <x.Type> [log2(c/3)] (SUBshiftLL <x.Type> x x [2]))
(MNEG x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo(c/5) -> (NEG (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2]))) (MNEG x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo(c/5) -> (NEG (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2])))
(MNEG x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo(c/7) -> (NEG (SLLconst <x.Type> [log2(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3]))) (MNEG x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo(c/7) -> (SLLconst <x.Type> [log2(c/7)] (SUBshiftLL <x.Type> x x [3]))
(MNEG x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo(c/9) -> (NEG (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3]))) (MNEG x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo(c/9) -> (NEG (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3])))
(MNEGW x (MOVDconst [c])) && int32(c)==-1 -> x (MNEGW x (MOVDconst [c])) && int32(c)==-1 -> x
...@@ -873,9 +873,9 @@ ...@@ -873,9 +873,9 @@
(MNEGW x (MOVDconst [c])) && isPowerOfTwo(c) -> (NEG (SLLconst <x.Type> [log2(c)] x)) (MNEGW x (MOVDconst [c])) && isPowerOfTwo(c) -> (NEG (SLLconst <x.Type> [log2(c)] x))
(MNEGW x (MOVDconst [c])) && isPowerOfTwo(c-1) && int32(c) >= 3 -> (NEG (ADDshiftLL <x.Type> x x [log2(c-1)])) (MNEGW x (MOVDconst [c])) && isPowerOfTwo(c-1) && int32(c) >= 3 -> (NEG (ADDshiftLL <x.Type> x x [log2(c-1)]))
(MNEGW x (MOVDconst [c])) && isPowerOfTwo(c+1) && int32(c) >= 7 -> (NEG (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log2(c+1)])) (MNEGW x (MOVDconst [c])) && isPowerOfTwo(c+1) && int32(c) >= 7 -> (NEG (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log2(c+1)]))
(MNEGW x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (NEG (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1]))) (MNEGW x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (SLLconst <x.Type> [log2(c/3)] (SUBshiftLL <x.Type> x x [2]))
(MNEGW x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (NEG (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2]))) (MNEGW x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (NEG (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2])))
(MNEGW x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (NEG (SLLconst <x.Type> [log2(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3]))) (MNEGW x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (SLLconst <x.Type> [log2(c/7)] (SUBshiftLL <x.Type> x x [3]))
(MNEGW x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (NEG (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3]))) (MNEGW x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (NEG (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3])))
// div by constant // div by constant
...@@ -1667,4 +1667,4 @@ ...@@ -1667,4 +1667,4 @@
(FSUBS a (FNMULS x y)) -> (FMADDS a x y) (FSUBS a (FNMULS x y)) -> (FMADDS a x y)
(FSUBD a (FNMULD x y)) -> (FMADDD a x y) (FSUBD a (FNMULD x y)) -> (FMADDD a x y)
(FSUBS (FNMULS x y) a) -> (FNMADDS a x y) (FSUBS (FNMULS x y) a) -> (FNMADDS a x y)
(FSUBD (FNMULD x y) a) -> (FNMADDD a x y) (FSUBD (FNMULD x y) a) -> (FNMADDD a x y)
\ No newline at end of file
...@@ -4828,7 +4828,7 @@ func rewriteValueARM64_OpARM64MNEG_10(v *Value) bool { ...@@ -4828,7 +4828,7 @@ func rewriteValueARM64_OpARM64MNEG_10(v *Value) bool {
} }
// match: (MNEG x (MOVDconst [c])) // match: (MNEG x (MOVDconst [c]))
// cond: c%3 == 0 && isPowerOfTwo(c/3) // cond: c%3 == 0 && isPowerOfTwo(c/3)
// result: (NEG (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1]))) // result: (SLLconst <x.Type> [log2(c/3)] (SUBshiftLL <x.Type> x x [2]))
for { for {
_ = v.Args[1] _ = v.Args[1]
x := v.Args[0] x := v.Args[0]
...@@ -4840,20 +4840,19 @@ func rewriteValueARM64_OpARM64MNEG_10(v *Value) bool { ...@@ -4840,20 +4840,19 @@ func rewriteValueARM64_OpARM64MNEG_10(v *Value) bool {
if !(c%3 == 0 && isPowerOfTwo(c/3)) { if !(c%3 == 0 && isPowerOfTwo(c/3)) {
break break
} }
v.reset(OpARM64NEG) v.reset(OpARM64SLLconst)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type) v.Type = x.Type
v0.AuxInt = log2(c / 3) v.AuxInt = log2(c / 3)
v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v1.AuxInt = 1 v0.AuxInt = 2
v1.AddArg(x) v0.AddArg(x)
v1.AddArg(x) v0.AddArg(x)
v0.AddArg(v1)
v.AddArg(v0) v.AddArg(v0)
return true return true
} }
// match: (MNEG (MOVDconst [c]) x) // match: (MNEG (MOVDconst [c]) x)
// cond: c%3 == 0 && isPowerOfTwo(c/3) // cond: c%3 == 0 && isPowerOfTwo(c/3)
// result: (NEG (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1]))) // result: (SLLconst <x.Type> [log2(c/3)] (SUBshiftLL <x.Type> x x [2]))
for { for {
_ = v.Args[1] _ = v.Args[1]
v_0 := v.Args[0] v_0 := v.Args[0]
...@@ -4865,14 +4864,13 @@ func rewriteValueARM64_OpARM64MNEG_10(v *Value) bool { ...@@ -4865,14 +4864,13 @@ func rewriteValueARM64_OpARM64MNEG_10(v *Value) bool {
if !(c%3 == 0 && isPowerOfTwo(c/3)) { if !(c%3 == 0 && isPowerOfTwo(c/3)) {
break break
} }
v.reset(OpARM64NEG) v.reset(OpARM64SLLconst)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type) v.Type = x.Type
v0.AuxInt = log2(c / 3) v.AuxInt = log2(c / 3)
v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v1.AuxInt = 1 v0.AuxInt = 2
v1.AddArg(x) v0.AddArg(x)
v1.AddArg(x) v0.AddArg(x)
v0.AddArg(v1)
v.AddArg(v0) v.AddArg(v0)
return true return true
} }
...@@ -4928,7 +4926,7 @@ func rewriteValueARM64_OpARM64MNEG_10(v *Value) bool { ...@@ -4928,7 +4926,7 @@ func rewriteValueARM64_OpARM64MNEG_10(v *Value) bool {
} }
// match: (MNEG x (MOVDconst [c])) // match: (MNEG x (MOVDconst [c]))
// cond: c%7 == 0 && isPowerOfTwo(c/7) // cond: c%7 == 0 && isPowerOfTwo(c/7)
// result: (NEG (SLLconst <x.Type> [log2(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3]))) // result: (SLLconst <x.Type> [log2(c/7)] (SUBshiftLL <x.Type> x x [3]))
for { for {
_ = v.Args[1] _ = v.Args[1]
x := v.Args[0] x := v.Args[0]
...@@ -4940,22 +4938,19 @@ func rewriteValueARM64_OpARM64MNEG_10(v *Value) bool { ...@@ -4940,22 +4938,19 @@ func rewriteValueARM64_OpARM64MNEG_10(v *Value) bool {
if !(c%7 == 0 && isPowerOfTwo(c/7)) { if !(c%7 == 0 && isPowerOfTwo(c/7)) {
break break
} }
v.reset(OpARM64NEG) v.reset(OpARM64SLLconst)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type) v.Type = x.Type
v0.AuxInt = log2(c / 7) v.AuxInt = log2(c / 7)
v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v1.AuxInt = 3 v0.AuxInt = 3
v2 := b.NewValue0(v.Pos, OpARM64NEG, x.Type) v0.AddArg(x)
v2.AddArg(x) v0.AddArg(x)
v1.AddArg(v2)
v1.AddArg(x)
v0.AddArg(v1)
v.AddArg(v0) v.AddArg(v0)
return true return true
} }
// match: (MNEG (MOVDconst [c]) x) // match: (MNEG (MOVDconst [c]) x)
// cond: c%7 == 0 && isPowerOfTwo(c/7) // cond: c%7 == 0 && isPowerOfTwo(c/7)
// result: (NEG (SLLconst <x.Type> [log2(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3]))) // result: (SLLconst <x.Type> [log2(c/7)] (SUBshiftLL <x.Type> x x [3]))
for { for {
_ = v.Args[1] _ = v.Args[1]
v_0 := v.Args[0] v_0 := v.Args[0]
...@@ -4967,16 +4962,13 @@ func rewriteValueARM64_OpARM64MNEG_10(v *Value) bool { ...@@ -4967,16 +4962,13 @@ func rewriteValueARM64_OpARM64MNEG_10(v *Value) bool {
if !(c%7 == 0 && isPowerOfTwo(c/7)) { if !(c%7 == 0 && isPowerOfTwo(c/7)) {
break break
} }
v.reset(OpARM64NEG) v.reset(OpARM64SLLconst)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type) v.Type = x.Type
v0.AuxInt = log2(c / 7) v.AuxInt = log2(c / 7)
v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v1.AuxInt = 3 v0.AuxInt = 3
v2 := b.NewValue0(v.Pos, OpARM64NEG, x.Type) v0.AddArg(x)
v2.AddArg(x) v0.AddArg(x)
v1.AddArg(v2)
v1.AddArg(x)
v0.AddArg(v1)
v.AddArg(v0) v.AddArg(v0)
return true return true
} }
...@@ -5325,7 +5317,7 @@ func rewriteValueARM64_OpARM64MNEGW_10(v *Value) bool { ...@@ -5325,7 +5317,7 @@ func rewriteValueARM64_OpARM64MNEGW_10(v *Value) bool {
} }
// match: (MNEGW x (MOVDconst [c])) // match: (MNEGW x (MOVDconst [c]))
// cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) // cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)
// result: (NEG (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1]))) // result: (SLLconst <x.Type> [log2(c/3)] (SUBshiftLL <x.Type> x x [2]))
for { for {
_ = v.Args[1] _ = v.Args[1]
x := v.Args[0] x := v.Args[0]
...@@ -5337,20 +5329,19 @@ func rewriteValueARM64_OpARM64MNEGW_10(v *Value) bool { ...@@ -5337,20 +5329,19 @@ func rewriteValueARM64_OpARM64MNEGW_10(v *Value) bool {
if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) { if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) {
break break
} }
v.reset(OpARM64NEG) v.reset(OpARM64SLLconst)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type) v.Type = x.Type
v0.AuxInt = log2(c / 3) v.AuxInt = log2(c / 3)
v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v1.AuxInt = 1 v0.AuxInt = 2
v1.AddArg(x) v0.AddArg(x)
v1.AddArg(x) v0.AddArg(x)
v0.AddArg(v1)
v.AddArg(v0) v.AddArg(v0)
return true return true
} }
// match: (MNEGW (MOVDconst [c]) x) // match: (MNEGW (MOVDconst [c]) x)
// cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) // cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)
// result: (NEG (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1]))) // result: (SLLconst <x.Type> [log2(c/3)] (SUBshiftLL <x.Type> x x [2]))
for { for {
_ = v.Args[1] _ = v.Args[1]
v_0 := v.Args[0] v_0 := v.Args[0]
...@@ -5362,14 +5353,13 @@ func rewriteValueARM64_OpARM64MNEGW_10(v *Value) bool { ...@@ -5362,14 +5353,13 @@ func rewriteValueARM64_OpARM64MNEGW_10(v *Value) bool {
if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) { if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) {
break break
} }
v.reset(OpARM64NEG) v.reset(OpARM64SLLconst)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type) v.Type = x.Type
v0.AuxInt = log2(c / 3) v.AuxInt = log2(c / 3)
v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v1.AuxInt = 1 v0.AuxInt = 2
v1.AddArg(x) v0.AddArg(x)
v1.AddArg(x) v0.AddArg(x)
v0.AddArg(v1)
v.AddArg(v0) v.AddArg(v0)
return true return true
} }
...@@ -5425,7 +5415,7 @@ func rewriteValueARM64_OpARM64MNEGW_10(v *Value) bool { ...@@ -5425,7 +5415,7 @@ func rewriteValueARM64_OpARM64MNEGW_10(v *Value) bool {
} }
// match: (MNEGW x (MOVDconst [c])) // match: (MNEGW x (MOVDconst [c]))
// cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) // cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)
// result: (NEG (SLLconst <x.Type> [log2(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3]))) // result: (SLLconst <x.Type> [log2(c/7)] (SUBshiftLL <x.Type> x x [3]))
for { for {
_ = v.Args[1] _ = v.Args[1]
x := v.Args[0] x := v.Args[0]
...@@ -5437,22 +5427,19 @@ func rewriteValueARM64_OpARM64MNEGW_10(v *Value) bool { ...@@ -5437,22 +5427,19 @@ func rewriteValueARM64_OpARM64MNEGW_10(v *Value) bool {
if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) { if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) {
break break
} }
v.reset(OpARM64NEG) v.reset(OpARM64SLLconst)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type) v.Type = x.Type
v0.AuxInt = log2(c / 7) v.AuxInt = log2(c / 7)
v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v1.AuxInt = 3 v0.AuxInt = 3
v2 := b.NewValue0(v.Pos, OpARM64NEG, x.Type) v0.AddArg(x)
v2.AddArg(x) v0.AddArg(x)
v1.AddArg(v2)
v1.AddArg(x)
v0.AddArg(v1)
v.AddArg(v0) v.AddArg(v0)
return true return true
} }
// match: (MNEGW (MOVDconst [c]) x) // match: (MNEGW (MOVDconst [c]) x)
// cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) // cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)
// result: (NEG (SLLconst <x.Type> [log2(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3]))) // result: (SLLconst <x.Type> [log2(c/7)] (SUBshiftLL <x.Type> x x [3]))
for { for {
_ = v.Args[1] _ = v.Args[1]
v_0 := v.Args[0] v_0 := v.Args[0]
...@@ -5464,16 +5451,13 @@ func rewriteValueARM64_OpARM64MNEGW_10(v *Value) bool { ...@@ -5464,16 +5451,13 @@ func rewriteValueARM64_OpARM64MNEGW_10(v *Value) bool {
if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) { if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) {
break break
} }
v.reset(OpARM64NEG) v.reset(OpARM64SLLconst)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type) v.Type = x.Type
v0.AuxInt = log2(c / 7) v.AuxInt = log2(c / 7)
v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v1.AuxInt = 3 v0.AuxInt = 3
v2 := b.NewValue0(v.Pos, OpARM64NEG, x.Type) v0.AddArg(x)
v2.AddArg(x) v0.AddArg(x)
v1.AddArg(v2)
v1.AddArg(x)
v0.AddArg(v1)
v.AddArg(v0) v.AddArg(v0)
return true return true
} }
...@@ -22073,4 +22057,4 @@ func rewriteBlockARM64(b *Block) bool { ...@@ -22073,4 +22057,4 @@ func rewriteBlockARM64(b *Block) bool {
} }
} }
return false return false
} }
\ No newline at end of file
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