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>
diff --git a/src/cmd/compile/internal/ssa/gen/Wasm.rules b/src/cmd/compile/internal/ssa/gen/Wasm.rules
index c10ff2f..ea12c5d 100644
--- a/src/cmd/compile/internal/ssa/gen/Wasm.rules
+++ b/src/cmd/compile/internal/ssa/gen/Wasm.rules
@@ -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)
diff --git a/src/cmd/compile/internal/ssa/rewriteWasm.go b/src/cmd/compile/internal/ssa/rewriteWasm.go
index 16e6f96..52b6f6b 100644
--- a/src/cmd/compile/internal/ssa/rewriteWasm.go
+++ b/src/cmd/compile/internal/ssa/rewriteWasm.go
@@ -591,6 +591,8 @@
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 @@
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 @@
}
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 @@
}
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]
diff --git a/test/codegen/comparisons.go b/test/codegen/comparisons.go
index 3c2dcb7..02bed38 100644
--- a/test/codegen/comparisons.go
+++ b/test/codegen/comparisons.go
@@ -456,3 +456,83 @@
}
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
+}