mirror of
https://github.com/golang/go.git
synced 2026-04-03 09:49:56 +09:00
cmd/compile: add identity and absorption rules for wasm
Add post-lowering identity and absorption rules for I64And, I64Or, I64Xor, and I64Mul with constant operands: (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 The generic SSA rules handle these patterns before lowering, but these rules catch cases where wasm-specific lowering or other post-lowering optimization passes produce new nodes with identity or absorbing constant operands. For example, the complement rule lowers Com64(x) to (I64Xor x (I64Const [-1])), and if x is later determined to be all-ones, the I64And absorption rule can fold the result to zero. Cq-Include-Trybots: luci.golang.try:gotip-wasip1-wasm_wasmtime,gotip-wasip1-wasm_wazero Change-Id: Ie9a40e075662d4828a70e30b258d92ee171d0bc2 Reviewed-on: https://go-review.googlesource.com/c/go/+/752861 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
committed by
Gopher Robot
parent
28b1d8886b
commit
def4e491be
@@ -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]))
|
||||
|
||||
@@ -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]))
|
||||
|
||||
Reference in New Issue
Block a user