cmd/compile: optimize unsigned comparisons with 0/1 on wasm

Updates #21439

Change-Id: I0fbcde6e0c2fc368fe686b271670f9d8be4a7900
Reviewed-on: https://go-review.googlesource.com/c/go/+/247557
Run-TryBot: Agniva De Sarker <agniva.quicksilver@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Richard Musiol <neelance@gmail.com>
This commit is contained in:
Agniva De Sarker 2020-08-08 15:19:42 +05:30 committed by Agniva De Sarker
parent 13e41bcde8
commit 8acbe4c0b3
3 changed files with 150 additions and 0 deletions

View File

@ -377,6 +377,10 @@
(I64Ne (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64Ne y (I64Const [x]))
(I64Eq x (I64Const [0])) => (I64Eqz x)
(I64LtU (I64Const [0]) x) => (I64Eqz (I64Eqz x))
(I64LeU x (I64Const [0])) => (I64Eqz x)
(I64LtU x (I64Const [1])) => (I64Eqz x)
(I64LeU (I64Const [1]) x) => (I64Eqz (I64Eqz x))
(I64Ne x (I64Const [0])) => (I64Eqz (I64Eqz x))
(I64Add x (I64Const [y])) => (I64AddConst [y] x)

View File

@ -591,6 +591,8 @@ func rewriteValueWasm(v *Value) bool {
return rewriteValueWasm_OpWasmI64Eq(v)
case OpWasmI64Eqz:
return rewriteValueWasm_OpWasmI64Eqz(v)
case OpWasmI64LeU:
return rewriteValueWasm_OpWasmI64LeU(v)
case OpWasmI64Load:
return rewriteValueWasm_OpWasmI64Load(v)
case OpWasmI64Load16S:
@ -605,6 +607,8 @@ func rewriteValueWasm(v *Value) bool {
return rewriteValueWasm_OpWasmI64Load8S(v)
case OpWasmI64Load8U:
return rewriteValueWasm_OpWasmI64Load8U(v)
case OpWasmI64LtU:
return rewriteValueWasm_OpWasmI64LtU(v)
case OpWasmI64Mul:
return rewriteValueWasm_OpWasmI64Mul(v)
case OpWasmI64Ne:
@ -3824,6 +3828,37 @@ func rewriteValueWasm_OpWasmI64Eqz(v *Value) bool {
}
return false
}
func rewriteValueWasm_OpWasmI64LeU(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
typ := &b.Func.Config.Types
// match: (I64LeU x (I64Const [0]))
// result: (I64Eqz x)
for {
x := v_0
if v_1.Op != OpWasmI64Const || auxIntToInt64(v_1.AuxInt) != 0 {
break
}
v.reset(OpWasmI64Eqz)
v.AddArg(x)
return true
}
// match: (I64LeU (I64Const [1]) x)
// result: (I64Eqz (I64Eqz x))
for {
if v_0.Op != OpWasmI64Const || auxIntToInt64(v_0.AuxInt) != 1 {
break
}
x := v_1
v.reset(OpWasmI64Eqz)
v0 := b.NewValue0(v.Pos, OpWasmI64Eqz, typ.Bool)
v0.AddArg(x)
v.AddArg(v0)
return true
}
return false
}
func rewriteValueWasm_OpWasmI64Load(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
@ -4070,6 +4105,37 @@ func rewriteValueWasm_OpWasmI64Load8U(v *Value) bool {
}
return false
}
func rewriteValueWasm_OpWasmI64LtU(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
typ := &b.Func.Config.Types
// match: (I64LtU (I64Const [0]) x)
// result: (I64Eqz (I64Eqz x))
for {
if v_0.Op != OpWasmI64Const || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
x := v_1
v.reset(OpWasmI64Eqz)
v0 := b.NewValue0(v.Pos, OpWasmI64Eqz, typ.Bool)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (I64LtU x (I64Const [1]))
// result: (I64Eqz x)
for {
x := v_0
if v_1.Op != OpWasmI64Const || auxIntToInt64(v_1.AuxInt) != 1 {
break
}
v.reset(OpWasmI64Eqz)
v.AddArg(x)
return true
}
return false
}
func rewriteValueWasm_OpWasmI64Mul(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]

View File

@ -456,3 +456,83 @@ func UintGeqOne(a uint8, b uint16, c uint32, d uint64) int {
}
return 0
}
func CmpToZeroU_ex1(a uint8, b uint16, c uint32, d uint64) int {
// wasm:"I64Eqz"-"I64LtU"
if 0 < a {
return 1
}
// wasm:"I64Eqz"-"I64LtU"
if 0 < b {
return 1
}
// wasm:"I64Eqz"-"I64LtU"
if 0 < c {
return 1
}
// wasm:"I64Eqz"-"I64LtU"
if 0 < d {
return 1
}
return 0
}
func CmpToZeroU_ex2(a uint8, b uint16, c uint32, d uint64) int {
// wasm:"I64Eqz"-"I64LeU"
if a <= 0 {
return 1
}
// wasm:"I64Eqz"-"I64LeU"
if b <= 0 {
return 1
}
// wasm:"I64Eqz"-"I64LeU"
if c <= 0 {
return 1
}
// wasm:"I64Eqz"-"I64LeU"
if d <= 0 {
return 1
}
return 0
}
func CmpToOneU_ex1(a uint8, b uint16, c uint32, d uint64) int {
// wasm:"I64Eqz"-"I64LtU"
if a < 1 {
return 1
}
// wasm:"I64Eqz"-"I64LtU"
if b < 1 {
return 1
}
// wasm:"I64Eqz"-"I64LtU"
if c < 1 {
return 1
}
// wasm:"I64Eqz"-"I64LtU"
if d < 1 {
return 1
}
return 0
}
func CmpToOneU_ex2(a uint8, b uint16, c uint32, d uint64) int {
// wasm:"I64Eqz"-"I64LeU"
if 1 <= a {
return 1
}
// wasm:"I64Eqz"-"I64LeU"
if 1 <= b {
return 1
}
// wasm:"I64Eqz"-"I64LeU"
if 1 <= c {
return 1
}
// wasm:"I64Eqz"-"I64LeU"
if 1 <= d {
return 1
}
return 0
}