aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/ssa/_gen/Wasm.rules10
-rw-r--r--src/cmd/compile/internal/ssa/rewriteWasm.go70
2 files changed, 80 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/_gen/Wasm.rules b/src/cmd/compile/internal/ssa/_gen/Wasm.rules
index 8490fb39b8..9b582c8c00 100644
--- a/src/cmd/compile/internal/ssa/_gen/Wasm.rules
+++ b/src/cmd/compile/internal/ssa/_gen/Wasm.rules
@@ -390,6 +390,16 @@
(I64ShrU (I64Const [x]) (I64Const [y])) => (I64Const [int64(uint64(x) >> uint64(y))])
(I64ShrS (I64Const [x]) (I64Const [y])) => (I64Const [x >> uint64(y)])
+// Identity and absorption rules for AND/OR/XOR/MUL.
+// These fire on nodes created during or after lowering.
+(I64And x (I64Const [-1])) => x
+(I64And x (I64Const [0])) => (I64Const [0])
+(I64Or x (I64Const [0])) => x
+(I64Or x (I64Const [-1])) => (I64Const [-1])
+(I64Xor x (I64Const [0])) => x
+(I64Mul x (I64Const [0])) => (I64Const [0])
+(I64Mul x (I64Const [1])) => x
+
// TODO: declare these operations as commutative and get rid of these rules?
(I64Add (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64Add y (I64Const [x]))
(I64Mul (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64Mul y (I64Const [x]))
diff --git a/src/cmd/compile/internal/ssa/rewriteWasm.go b/src/cmd/compile/internal/ssa/rewriteWasm.go
index 68a40f0c7f..c0ccd9611d 100644
--- a/src/cmd/compile/internal/ssa/rewriteWasm.go
+++ b/src/cmd/compile/internal/ssa/rewriteWasm.go
@@ -3949,6 +3949,26 @@ func rewriteValueWasm_OpWasmI64And(v *Value) bool {
v.AuxInt = int64ToAuxInt(x & y)
return true
}
+ // match: (I64And x (I64Const [-1]))
+ // result: x
+ for {
+ x := v_0
+ if v_1.Op != OpWasmI64Const || auxIntToInt64(v_1.AuxInt) != -1 {
+ break
+ }
+ v.copyOf(x)
+ return true
+ }
+ // match: (I64And x (I64Const [0]))
+ // result: (I64Const [0])
+ for {
+ if v_1.Op != OpWasmI64Const || auxIntToInt64(v_1.AuxInt) != 0 {
+ break
+ }
+ v.reset(OpWasmI64Const)
+ v.AuxInt = int64ToAuxInt(0)
+ return true
+ }
// match: (I64And (I64Const [x]) y)
// cond: y.Op != OpWasmI64Const
// result: (I64And y (I64Const [x]))
@@ -4448,6 +4468,26 @@ func rewriteValueWasm_OpWasmI64Mul(v *Value) bool {
v.AuxInt = int64ToAuxInt(x * y)
return true
}
+ // match: (I64Mul x (I64Const [0]))
+ // result: (I64Const [0])
+ for {
+ if v_1.Op != OpWasmI64Const || auxIntToInt64(v_1.AuxInt) != 0 {
+ break
+ }
+ v.reset(OpWasmI64Const)
+ v.AuxInt = int64ToAuxInt(0)
+ return true
+ }
+ // match: (I64Mul x (I64Const [1]))
+ // result: x
+ for {
+ x := v_0
+ if v_1.Op != OpWasmI64Const || auxIntToInt64(v_1.AuxInt) != 1 {
+ break
+ }
+ v.copyOf(x)
+ return true
+ }
// match: (I64Mul (I64Const [x]) y)
// cond: y.Op != OpWasmI64Const
// result: (I64Mul y (I64Const [x]))
@@ -4564,6 +4604,26 @@ func rewriteValueWasm_OpWasmI64Or(v *Value) bool {
v.AuxInt = int64ToAuxInt(x | y)
return true
}
+ // match: (I64Or x (I64Const [0]))
+ // result: x
+ for {
+ x := v_0
+ if v_1.Op != OpWasmI64Const || auxIntToInt64(v_1.AuxInt) != 0 {
+ break
+ }
+ v.copyOf(x)
+ return true
+ }
+ // match: (I64Or x (I64Const [-1]))
+ // result: (I64Const [-1])
+ for {
+ if v_1.Op != OpWasmI64Const || auxIntToInt64(v_1.AuxInt) != -1 {
+ break
+ }
+ v.reset(OpWasmI64Const)
+ v.AuxInt = int64ToAuxInt(-1)
+ return true
+ }
// match: (I64Or (I64Const [x]) y)
// cond: y.Op != OpWasmI64Const
// result: (I64Or y (I64Const [x]))
@@ -4788,6 +4848,16 @@ func rewriteValueWasm_OpWasmI64Xor(v *Value) bool {
v.AuxInt = int64ToAuxInt(x ^ y)
return true
}
+ // match: (I64Xor x (I64Const [0]))
+ // result: x
+ for {
+ x := v_0
+ if v_1.Op != OpWasmI64Const || auxIntToInt64(v_1.AuxInt) != 0 {
+ break
+ }
+ v.copyOf(x)
+ return true
+ }
// match: (I64Xor (I64Const [x]) y)
// cond: y.Op != OpWasmI64Const
// result: (I64Xor y (I64Const [x]))