mirror of
https://github.com/golang/go
synced 2024-11-11 19:41:36 -07:00
cmd/compile: optimize bounded shifts on wasm
Use the shiftIsBounded function to generate more efficient Shift instructions. Updates #25167 Change-Id: Id350f8462dc3a7ed3bfed0bcbea2860b8f40048a Reviewed-on: https://go-review.googlesource.com/c/go/+/182558 Run-TryBot: Agniva De Sarker <agniva.quicksilver@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Richard Musiol <neelance@gmail.com>
This commit is contained in:
parent
b9ef4c0f56
commit
8fedb2d338
@ -102,6 +102,7 @@
|
|||||||
// Lowering shifts
|
// Lowering shifts
|
||||||
// Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
|
// Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
|
||||||
|
|
||||||
|
(Lsh64x64 x y) && shiftIsBounded(v) -> (I64Shl x y)
|
||||||
(Lsh64x64 x y) -> (Select (I64Shl x y) (I64Const [0]) (I64LtU y (I64Const [64])))
|
(Lsh64x64 x y) -> (Select (I64Shl x y) (I64Const [0]) (I64LtU y (I64Const [64])))
|
||||||
(Lsh64x(32|16|8) x y) -> (Lsh64x64 x (ZeroExt(32|16|8)to64 y))
|
(Lsh64x(32|16|8) x y) -> (Lsh64x64 x (ZeroExt(32|16|8)to64 y))
|
||||||
|
|
||||||
@ -114,6 +115,7 @@
|
|||||||
(Lsh8x64 x y) -> (Lsh64x64 x y)
|
(Lsh8x64 x y) -> (Lsh64x64 x y)
|
||||||
(Lsh8x(32|16|8) x y) -> (Lsh64x64 x (ZeroExt(32|16|8)to64 y))
|
(Lsh8x(32|16|8) x y) -> (Lsh64x64 x (ZeroExt(32|16|8)to64 y))
|
||||||
|
|
||||||
|
(Rsh64Ux64 x y) && shiftIsBounded(v) -> (I64ShrU x y)
|
||||||
(Rsh64Ux64 x y) -> (Select (I64ShrU x y) (I64Const [0]) (I64LtU y (I64Const [64])))
|
(Rsh64Ux64 x y) -> (Select (I64ShrU x y) (I64Const [0]) (I64LtU y (I64Const [64])))
|
||||||
(Rsh64Ux(32|16|8) x y) -> (Rsh64Ux64 x (ZeroExt(32|16|8)to64 y))
|
(Rsh64Ux(32|16|8) x y) -> (Rsh64Ux64 x (ZeroExt(32|16|8)to64 y))
|
||||||
|
|
||||||
@ -129,6 +131,7 @@
|
|||||||
// Signed right shift needs to return 0/-1 if shift amount is >= width of shifted value.
|
// Signed right shift needs to return 0/-1 if shift amount is >= width of shifted value.
|
||||||
// We implement this by setting the shift value to (width - 1) if the shift value is >= width.
|
// We implement this by setting the shift value to (width - 1) if the shift value is >= width.
|
||||||
|
|
||||||
|
(Rsh64x64 x y) && shiftIsBounded(v) -> (I64ShrS x y)
|
||||||
(Rsh64x64 x y) -> (I64ShrS x (Select <typ.Int64> y (I64Const [63]) (I64LtU y (I64Const [64]))))
|
(Rsh64x64 x y) -> (I64ShrS x (Select <typ.Int64> y (I64Const [63]) (I64LtU y (I64Const [64]))))
|
||||||
(Rsh64x(32|16|8) x y) -> (Rsh64x64 x (ZeroExt(32|16|8)to64 y))
|
(Rsh64x(32|16|8) x y) -> (Rsh64x64 x (ZeroExt(32|16|8)to64 y))
|
||||||
|
|
||||||
|
@ -2729,6 +2729,20 @@ func rewriteValueWasm_OpLsh64x64_0(v *Value) bool {
|
|||||||
b := v.Block
|
b := v.Block
|
||||||
typ := &b.Func.Config.Types
|
typ := &b.Func.Config.Types
|
||||||
// match: (Lsh64x64 x y)
|
// match: (Lsh64x64 x y)
|
||||||
|
// cond: shiftIsBounded(v)
|
||||||
|
// result: (I64Shl x y)
|
||||||
|
for {
|
||||||
|
y := v.Args[1]
|
||||||
|
x := v.Args[0]
|
||||||
|
if !(shiftIsBounded(v)) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpWasmI64Shl)
|
||||||
|
v.AddArg(x)
|
||||||
|
v.AddArg(y)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (Lsh64x64 x y)
|
||||||
// cond:
|
// cond:
|
||||||
// result: (Select (I64Shl x y) (I64Const [0]) (I64LtU y (I64Const [64])))
|
// result: (Select (I64Shl x y) (I64Const [0]) (I64LtU y (I64Const [64])))
|
||||||
for {
|
for {
|
||||||
@ -4256,6 +4270,20 @@ func rewriteValueWasm_OpRsh64Ux64_0(v *Value) bool {
|
|||||||
b := v.Block
|
b := v.Block
|
||||||
typ := &b.Func.Config.Types
|
typ := &b.Func.Config.Types
|
||||||
// match: (Rsh64Ux64 x y)
|
// match: (Rsh64Ux64 x y)
|
||||||
|
// cond: shiftIsBounded(v)
|
||||||
|
// result: (I64ShrU x y)
|
||||||
|
for {
|
||||||
|
y := v.Args[1]
|
||||||
|
x := v.Args[0]
|
||||||
|
if !(shiftIsBounded(v)) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpWasmI64ShrU)
|
||||||
|
v.AddArg(x)
|
||||||
|
v.AddArg(y)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (Rsh64Ux64 x y)
|
||||||
// cond:
|
// cond:
|
||||||
// result: (Select (I64ShrU x y) (I64Const [0]) (I64LtU y (I64Const [64])))
|
// result: (Select (I64ShrU x y) (I64Const [0]) (I64LtU y (I64Const [64])))
|
||||||
for {
|
for {
|
||||||
@ -4333,6 +4361,20 @@ func rewriteValueWasm_OpRsh64x64_0(v *Value) bool {
|
|||||||
b := v.Block
|
b := v.Block
|
||||||
typ := &b.Func.Config.Types
|
typ := &b.Func.Config.Types
|
||||||
// match: (Rsh64x64 x y)
|
// match: (Rsh64x64 x y)
|
||||||
|
// cond: shiftIsBounded(v)
|
||||||
|
// result: (I64ShrS x y)
|
||||||
|
for {
|
||||||
|
y := v.Args[1]
|
||||||
|
x := v.Args[0]
|
||||||
|
if !(shiftIsBounded(v)) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpWasmI64ShrS)
|
||||||
|
v.AddArg(x)
|
||||||
|
v.AddArg(y)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (Rsh64x64 x y)
|
||||||
// cond:
|
// cond:
|
||||||
// result: (I64ShrS x (Select <typ.Int64> y (I64Const [63]) (I64LtU y (I64Const [64]))))
|
// result: (I64ShrS x (Select <typ.Int64> y (I64Const [63]) (I64LtU y (I64Const [64]))))
|
||||||
for {
|
for {
|
||||||
|
@ -102,9 +102,9 @@ func lshSignedMasked(v8 int8, v16 int16, v32 int32, v64 int64, x int) {
|
|||||||
// bounded shifts //
|
// bounded shifts //
|
||||||
// ------------------ //
|
// ------------------ //
|
||||||
|
|
||||||
func lshGuarded64(v int64, s uint) int64 {
|
func rshGuarded64(v int64, s uint) int64 {
|
||||||
if s < 64 {
|
if s < 64 {
|
||||||
// s390x:-".*AND",-".*MOVDGE"
|
// s390x:-".*AND",-".*MOVDGE" wasm:-"Select",-".*LtU"
|
||||||
return v >> s
|
return v >> s
|
||||||
}
|
}
|
||||||
panic("shift too large")
|
panic("shift too large")
|
||||||
@ -112,15 +112,15 @@ func lshGuarded64(v int64, s uint) int64 {
|
|||||||
|
|
||||||
func rshGuarded64U(v uint64, s uint) uint64 {
|
func rshGuarded64U(v uint64, s uint) uint64 {
|
||||||
if s < 64 {
|
if s < 64 {
|
||||||
// s390x:-".*AND",-".*MOVDGE"
|
// s390x:-".*AND",-".*MOVDGE" wasm:-"Select",-".*LtU"
|
||||||
return v >> s
|
return v >> s
|
||||||
}
|
}
|
||||||
panic("shift too large")
|
panic("shift too large")
|
||||||
}
|
}
|
||||||
|
|
||||||
func rshGuarded64(v int64, s uint) int64 {
|
func lshGuarded64(v int64, s uint) int64 {
|
||||||
if s < 64 {
|
if s < 64 {
|
||||||
// s390x:-".*AND",-".*MOVDGE"
|
// s390x:-".*AND",-".*MOVDGE" wasm:-"Select",-".*LtU"
|
||||||
return v << s
|
return v << s
|
||||||
}
|
}
|
||||||
panic("shift too large")
|
panic("shift too large")
|
||||||
|
Loading…
Reference in New Issue
Block a user