diff options
| author | George Adams <georgeadams1995@gmail.com> | 2026-03-10 12:36:29 +0000 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2026-03-10 20:07:23 -0700 |
| commit | bd5dc3a2fbde68835326d3b1d9fc480bcf6da086 (patch) | |
| tree | 15a668002ca196d031bdf912cf317634b129468e /src/cmd/compile/internal/ssa | |
| parent | 935ba2e486d035c60104217eec8f2a223cdb3bef (diff) | |
| download | go-bd5dc3a2fbde68835326d3b1d9fc480bcf6da086.tar.xz | |
cmd/compile: add double-mask elimination rule for wasm
Add a rule to collapse cascaded I64And operations with constant masks
into a single mask:
(I64And (I64And x (I64Const [c1])) (I64Const [c2])) =>
(I64And x (I64Const [c1 & c2]))
This pattern arises from sub-word comparisons. For example,
(Eq32 x y) lowers to (I64Eq (ZeroExt32to64 x) (ZeroExt32to64 y)),
which becomes (I64Eq (I64And x 0xffffffff) (I64And y 0xffffffff)).
If x or y is the result of another sub-word operation that already
inserted a mask, the masks cascade and this rule collapses them.
Cq-Include-Trybots: luci.golang.try:gotip-wasip1-wasm_wasmtime,gotip-wasip1-wasm_wazero
Change-Id: Id7856b391be3ac20f1bc9eee40995b52c0754aed
Reviewed-on: https://go-review.googlesource.com/c/go/+/753620
Reviewed-by: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Mark Freeman <markfreeman@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/ssa')
| -rw-r--r-- | src/cmd/compile/internal/ssa/_gen/Wasm.rules | 4 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/rewriteWasm.go | 23 |
2 files changed, 27 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/_gen/Wasm.rules b/src/cmd/compile/internal/ssa/_gen/Wasm.rules index 9b582c8c00..5e0c9304b5 100644 --- a/src/cmd/compile/internal/ssa/_gen/Wasm.rules +++ b/src/cmd/compile/internal/ssa/_gen/Wasm.rules @@ -400,6 +400,10 @@ (I64Mul x (I64Const [0])) => (I64Const [0]) (I64Mul x (I64Const [1])) => x +// Double-mask elimination: cascaded zero-extensions produce +// (I64And (I64And x C1) C2) which can be collapsed to a single mask. +(I64And (I64And x (I64Const [c1])) (I64Const [c2])) => (I64And x (I64Const [c1 & c2])) + // 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 c0ccd9611d..80c783e568 100644 --- a/src/cmd/compile/internal/ssa/rewriteWasm.go +++ b/src/cmd/compile/internal/ssa/rewriteWasm.go @@ -3969,6 +3969,29 @@ func rewriteValueWasm_OpWasmI64And(v *Value) bool { v.AuxInt = int64ToAuxInt(0) return true } + // match: (I64And (I64And x (I64Const [c1])) (I64Const [c2])) + // result: (I64And x (I64Const [c1 & c2])) + for { + if v_0.Op != OpWasmI64And { + break + } + _ = v_0.Args[1] + x := v_0.Args[0] + v_0_1 := v_0.Args[1] + if v_0_1.Op != OpWasmI64Const { + break + } + c1 := auxIntToInt64(v_0_1.AuxInt) + if v_1.Op != OpWasmI64Const { + break + } + c2 := auxIntToInt64(v_1.AuxInt) + v.reset(OpWasmI64And) + v0 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64) + v0.AuxInt = int64ToAuxInt(c1 & c2) + v.AddArg2(x, v0) + return true + } // match: (I64And (I64Const [x]) y) // cond: y.Op != OpWasmI64Const // result: (I64And y (I64Const [x])) |
